記憶體分配是作業系統必須面對的乙個環節,除非這個系統本身不需要記憶體安排,所有業務可以通過全域性資料和堆疊搞定。記憶體分配其實不困難,但是由記憶體引申出來的東西就比較複雜了。早前沒有mmu,系統本身的空間和使用者空間沒有優先順序之分,所以不同的程式之間的記憶體都是共享的,相互影響也是不可避免的。所以,一般來說,除了記憶體分配之外,還需要一些日誌資訊、檢測資訊幫助我們進行除錯和分析。當然,這些都不是我們關心的內容,我們關注的就是記憶體有哪些通用的分配演算法。
(1)固定記憶體分配
固定記憶體分配演算法是最簡單的演算法,也是最好理解的演算法。比如說有16m記憶體,現在我們假設分配的基本記憶體是4k,那麼總共有16m/4k = 4k個單元。所以,如果使用者想申請記憶體,最多就是4k次。如果使用者想要多一點記憶體,那麼系統把相鄰的記憶體分給使用者使用即可。
(2)鍊錶記憶體分配
固定記憶體分配雖然好,但是還有乙個缺點,那就是如果存在很多的浪費機會。試想一下,如果使用者只要幾十個byte,那麼也要分配給它4k個位元組,浪費的空間超過了99%。所以在此基礎之上,我們提出了鍊錶記憶體演算法。鍊錶演算法中儲存有空閒結點,記憶體釋放的時候,那麼記憶體查到空閒結點,該合併合併,該釋放的釋放;當然如果要申請記憶體的話,那方法就多了去了,可以最差申請、最優申請、最好申請,這些都是可以的。
(3)夥伴演算法
鍊錶演算法相比較固定記憶體演算法,可以節省不少記憶體。但是鍊錶演算法本身有乙個特點,那就是容易形成記憶體碎片。所以,我們可以結合固定分配和鍊錶演算法的特點,把記憶體分配成8、16、32、64、128、256、512大小的幾種鍊錶。鍊錶內部的大小都是相同的,鍊錶之間是倍數的關係。分配記憶體的時候,我們首先尋找最合適的鍊錶,然後分配記憶體,如果記憶體空間不夠,可以向高一級的記憶體鍊錶申請,這樣拆解下來的記憶體可以分配到低一級別的鍊錶;釋放記憶體的時候,我們也要注意記憶體的合併和組合。
(4)基於記憶體池的夥伴演算法
夥伴演算法固然好,但是如果某一種記憶體申請特別頻繁,那麼在夥伴演算法中就需要進行反覆的拆分和合併處理。一方面,這會影響了記憶體的分配效率,另外一方面也比較容易造成記憶體的分配碎片。所以,我們可以在夥伴演算法的基礎之上構建乙個記憶體池,在記憶體釋放的時候,只是標註當前記憶體不再使用,但是並沒有真正釋放,等到記憶體池中所有的記憶體都不再使用的時候再進行釋放,這在一定的程度上會提高記憶體的分配效率。特別是系統執行一段時間後,這種效果是特別明顯的。
(5)工作集演算法
工作集的演算法本質上說不是一種演算法,它只是一種基本思想。我們知道,在系統穩定之後,記憶體中分配的大小、配置的比例關係都是相對固定的,變化不是特別大。如果我們可以把這些資料給記錄下來,在系統啟動的時候預先分配好這些記憶體,那麼不就可以提公升系統的啟動速度了嗎?當然工作集中的引數設定更多的是一種經驗值,它需要我們綜合各種因素進行分析,反覆比較才會得出比較好的結果。
這五種演算法只是給出了基本思想,只有付出於實踐,多加操練才能從中有所收穫。
嵌入式作業系統核心原理和開發(中斷)
在我個人看來,中斷是cpu最重要的特色。從某種意義上來說,沒有中斷就沒有嵌入式作業系統。一旦你明白了中斷的真正含義,你對作業系統的了解就算真正入門了。什麼是中斷呢?我們可以看看微控制器下面是怎麼做的。include sbit led p1 6 unsigned int led enable 0 vo...
嵌入式作業系統核心原理和開發(開篇)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!作業系統是很多人每天必須打交道的東西,因為在你開啟電腦的一剎那,隨著bios自檢結束,你的windows系統已經開始執行了。如果問大家作業系統是什麼?可能有的人會說作業系統就是windows,就是那些可以放大 縮小 移動的視窗。對曾經是計算機專業的...
linux 嵌入式作業系統核心原理和開發總結
01 嵌入式作業系統核心原理和開發 優先順序的修改 02 嵌入式作業系統核心原理和開發 改進的鍊錶記憶體分配演算法 03 嵌入式作業系統核心原理和開發 等值block記憶體池設計 04 嵌入式作業系統核心原理和開發 執行緒狀態 05 嵌入式作業系統核心原理和開發 實時系統中的定時器 06 嵌入式作業...