linux核心的夥伴演算法最大限度的減少了記憶體的碎片,其實應該說成是盡自己最大的努力減少了記憶體 的碎片。其思想就是將物理記憶體分成10個鍊錶,每乙個鍊錶的元素代表一系列的連續頁面,連續頁面的數量隨鍊錶的不同而不同,linux中有10個這樣的鏈 表,按照2的從0到9次冪的連續頁面數量組成,比如鍊錶0中儲存有代表2的0次冪個連續頁面的頁面,而鍊錶k中儲存有2的k次冪個連續的頁面,linux 的夥伴系統的精髓不但是如何分配,更重要的是如何釋放,具體來講,釋放的過程就是乙個合併的過程--反之分配的過程就是乙個分解或者直接分配的過程,最終 的結果就是盡可能的得到盡可能大的連續記憶體塊,因為在有連續記憶體分配需求的時候,大的塊可以分解,然而小的非連續的塊由於其非連續卻不能合併,因此確保連 續塊的最大化總是好的,在分配小塊的時候,如果在小的塊鍊錶中沒有空閒塊,那麼就從較大的塊中分配,比如從它的order+1的塊中進行分配,結果就是一 個塊被分配了,由order+1塊分解出來的剩餘的乙個塊空閒,並且插入到order鍊錶,如果由order大小的需求那麼就可以分配之,如果沒有,那麼 就等著剛剛分配的塊釋放後再次和其合併成2的order+1次冪個連續頁面大小的塊。
在分配過程中由大塊分解而成的小塊中沒有被分配的塊將一直等著被分配的塊被釋放從而和其合併,合併的操作正是在頁面釋放的過程中,最終的結果就是相當與沒 有分解大塊,夥伴系統一直在向這個結果收斂,這就是為何夥伴系統能避免碎片的原因。夥伴系統在分配和釋放兩個方向上執行分解和合併兩個互逆的操作,如果一 開始系統沒有碎片,那麼最終的碎片將最小化,因為互逆的操作將最大力度的抵消碎片的產生,這就是精髓了。夥伴在這裡的意義包含幾種情況,一對夥伴表示兩個 塊,按照從0開始的索引,一對夥伴就是從偶數開始到其相鄰奇數的兩個相鄰的塊,如果order為0,那麼k/k+1(k為偶數)就是一對夥伴,如果 order為2,那麼k/k+2(k為偶數)就是一對夥伴,夥伴就是兩個相鄰的塊,它們的關係有三種,第一就是乙個被分配時,那麼另乙個就等著這個分配出 去的塊被釋放後合併,然後遞迴的進行更大order的合併;第二就是如果兩個都被分配,那麼肯定有乙個先被釋放,那麼化為情況一,注意在等待夥伴被釋放的 同時,該塊可以被分配,從而情況一化為情況二,但是最終它們結果總是趨向於情況三,也就是都被釋放從而被合併然後插入到更大一層的鍊錶中。
具體到**上就沒有理論那麼琅琅上口了,如果你看的是早期版本,會發現每乙個鍊錶都有乙個位圖,該位圖展示該鍊錶中夥伴的情況,該位圖設計上十分複雜,最 終被追求簡單的核心無情拋棄,2.6.28核心版本是比較新的版本了,它裡面沒有用位圖,而是直接判斷,具體在__free_one_page中體現:
static inline void __free_one_page(struct page *page,
linux記憶體管理 使用者空間和核心空間
關於虛擬記憶體有三點需要注意 上圖展示了整個程序位址空間的分布,其中4g的位址空間分為兩部分,在使用者空間內,對應了記憶體分布的五個段 資料段 段 bss段 堆 棧。在上篇文章中有詳細的介紹。這個圖示核心使用者空間的劃分,圖中最重要的就是高階記憶體的對映 其中kmalloc和vmalloc函式申請的...
linux記憶體管理 使用者空間和核心空間
關於虛擬記憶體有三點需要注意 上圖展示了整個程序位址空間的分布,其中4g的位址空間分為兩部分,在使用者空間內,對應了記憶體分布的五個段 資料段 段 bss段 堆 棧。在上篇文章中有詳細的介紹。這個圖示核心使用者空間的劃分,圖中最重要的就是高階記憶體的對映 其中kmalloc和vmalloc函式申請的...
linux記憶體管理 使用者空間和核心空間
關於虛擬記憶體有三點需要注意 上圖展示了整個程序位址空間的分布,其中4g的位址空間分為兩部分,在使用者空間內,對應了記憶體分布的五個段 資料段 段 bss段 堆 棧。在上篇文章中有詳細的介紹。這個圖示核心使用者空間的劃分,圖中最重要的就是高階記憶體的對映 其中kmalloc和vmalloc函式申請的...