在系統初始化進行到夥伴系統分配器可以承擔內存管理的責任後,必須停用bootmem分配器,畢竟不能同時用兩個分配器管理內存。在UMA和 NUMA系統上,停用分別由free_all_bootmem和free_all_bootmem_node完成(前面的博客已經詳細討論過)。夥伴系統 基於一種相對簡單而使人吃驚的強大算法,它結合了優秀內存分配器的兩個關鍵特性:速度和效率。Linux內核中採用了一種同時適用於32位和64位系統的 內存分頁模型,對於32位系統來講,兩級頁表足夠用了,而在x86_64系統中,用到了四級頁表,四級頁表分別爲:node
頁全局目錄(Page Global Directory)算法
頁上級目錄(Page Upper Directory)跨域
頁中間目錄(Page Middle Directory)spa
頁表(Page Table).net
頁全局目錄包含若干頁上級目錄的地址,頁上級目錄又依次包含若干頁中間目錄的地址,而頁中間目錄又包含若干頁表的地址,每個頁表項指向一個頁框。Linux中採用4KBcode
大小的頁框做爲標準的內存分配單元。
在實際應用中,常常須要分配一組連續的頁框,而頻繁地申請和釋放不一樣大小的連續頁框,必然致使在已分配頁框的內存塊中分散了許多小塊的空閒頁框。這樣,即便這些頁框 是空閒的,其餘須要分配連續頁框的應用也很可貴到知足。爲了不出現這種狀況,Linux內核中引入了夥伴系統算法(buddy system)。把全部的空閒頁框分組爲11個塊鏈表,每一個塊鏈表分別包含大小爲1,2,4,8,16,32,64,128,256,512和1024個連續頁框的頁框塊。最大能夠申請1024個連續頁框,對應4MB大小的連續內存。每一個頁框塊的第一個頁框的物理地址是該塊大小的整數倍。假設要申請一個256個頁框的塊,先從256個頁框的鏈表中查找空閒塊,若是沒有,就去512個頁框的鏈表中找,找到了則將頁框塊分爲2個256個頁框的塊,一個分配給應用,另一個移到256個頁框的鏈表中。若是512個頁框的鏈表中仍沒有空閒塊,繼續向1024個頁框的鏈表查找,若是仍然沒有,則返回錯誤。 頁框塊在釋放時,會主動將兩個連續的頁框塊合併爲一個較大的頁框塊。
爲清楚瞭解其分配製度,先給個夥伴系統數據的存儲框圖以下:
也就是每一個order對應一個free_area結構,free_area以不一樣的類型以鏈表的方式存儲這些內存塊。blog
主要的數據域結構分析:內存