夥伴系統(buddy system)
當一個請求需要分配m個物理頁,buddy system會尋找一個有\(2^n\)頁的塊(\(2^n-1 < m < 2^n\))分配給他。
我們使用一個空閒連結串列陣列實現buddy system,其中a[i]代表塊大小為\(2^i個頁\)(每頁為4kb)
假設我們要分配15kb記憶體,根據buddy system,我們需要尋找一個16kb(4頁)大小的塊
因為有4頁,所以我們需要檢視連結串列陣列的第2項(代表\(2^2\))。
由下圖發現,陣列的第二項為空,代表此時還沒有16kb大小的空閒塊。
buddy system會繼續查詢更大的塊(圖中為32kb),將32kb進行分類操作,獲得兩個16kb大小的塊。
將其中一個用於服務請求,另一個則插入到第2條連結串列(陣列的第二項)
SLAB分配器
buddy system最小的分配單位為1頁(4k)。但很多時候,核心需要分配的記憶體大小遠小於4k,這時候如果還用buddy system會出現嚴重的內部碎片問題。於是有了用於分配小記憶體的SLAB分配器。
SLAB分配器只分配大小固定的記憶體塊,對於每一種塊的大小,SLAB都會用獨立的記憶體資源池進行分配
SLAB分配器向buddy system申請一定大小的實體記憶體,並將獲得的實體記憶體塊作為一個slab(一個資料結構)。slab被劃分為等長的小塊記憶體,被組織成空閒連結串列的形式
所有的分配請求從current指標指向的slab中獲得空閒記憶體塊。當SLAB分配器接受一個分配請求時,它首先定位最適合大小的記憶體資源池,從current指標指向的slab中拿出一個空閒塊。
若拿出一個空閒塊後,該slab不再擁有空閒塊,則這個slab中的記憶體塊已經全部分配完了。發生兩個移動 : 將該slab移動到full裡面來,並從partial指向的連結串列中取出一個slab交給current。
當釋放一個塊到相應的slab空閒連結串列中,若該slab已全部分配完,則移動到partial,若原本僅分配出一塊,那麼將其釋放還給buddy system