本文所述關於內存管理的系列文章主要是對陳莉君老師所講述的內存管理知識講座的整理。前端
本講座主要分三個主題展開對內存管理進行講解:內存管理的硬件基礎、虛擬地址空間的管理、物理地址空間的管理.node
本文將主要以X86架構爲例來介紹夥伴算法和slab分配算法
Linux的夥伴算法將全部的空閒頁面分紅MAX_ORDER+1(MAX_ORDER默認大小爲11)個塊鏈表數組
每一個鏈表中的一個節點指向一個含有2的冪次個頁面的塊,即頁塊或簡稱塊緩存
圖 夥伴算法結構實例圖數據結構
0:每一個頁塊的大小爲1個頁架構
1:每一個頁塊的大小爲2個頁函數
。。。性能
MAX_ORDER:每一個頁塊的大小爲2的MAX_ORDER次方個頁3d
大小相同、物理地址連續的兩個頁塊稱爲夥伴
首先在大小知足要求的塊鏈表中查找是否有空閒塊,如有則直接分配,不然在更大的塊的塊鏈表中查找;
逆過程是塊的釋放,此時會把知足夥伴關係的塊合併,組成一個更大的塊,並插入到相應的塊鏈表中
每一個頁框對應一個struct page實例
每一個內存區關聯一個struct zone區域,該結構中用free_area數組對空閒頁框進行管理
負責大塊連續物理內存的分配和釋放,以頁框爲基本單位,避免外部碎片
負責小塊物理內存的分配,而且它也做爲一個緩存,主要針對內核中常常分配並釋放的對象
內核常常請求和釋放單個頁框,該緩存包含預先分配的頁框,用於知足本地CPU發出的單一頁框請求
若是分配階爲i的頁框塊,那麼先從第i條頁框塊鏈表中查找是否存在這麼大小的空閒塊。若是有則分配,不然在第i+1條鏈表中繼續查找,直到找到爲止
若是申請大小爲8個(分配階爲3)頁的頁塊,但卻在頁塊大小爲32(分配階爲5)的鏈表中找到空閒塊,則先將這32個頁面對半等分,前一半做爲分配使用,另外一半做爲新元素插入下級大小爲16(分配階爲4)的鏈表中;
繼續將前一半大小爲16的頁塊等分,一半分配,另外一半插入大小爲8(分配階爲3)的鏈表中
5節描述的夥伴算法經過__rmqueue()主要調用以下兩個函數:
在指定的內存分配區上,從說請求分配階order對應的鏈表開始查找所需大小的空閒塊,若是不成功者從高一階的鏈表上繼續查找
若是所獲得的內存塊大於說請求的內存塊,則按照夥伴算法的分配原理將大的頁框塊分裂爲小的頁框塊
基於夥伴算法、每CPU高速緩存和slab高速緩存造成兩種內存分配器
處理對連續頁框的內存分配請求。分區頁框分配器分爲兩大部分:前端的管理區分配器和夥伴系統
管理區分配器負責搜索一個能知足請求頁框大小的管理區;
在每一個管理區中,具體的頁框分配工做由夥伴系統負責,爲了達到更好的性能,單個頁框的申請直接由每cpu頁框高速緩存完成
圖 分區頁框分配器示例圖
將各類分配對象分區放進高速緩存,即每一個高速緩存都對同類型分配對象的一種「儲備」
圖 頁框分配函數的關係
進程調用malloc()->
得到一塊虛擬內存->
內存訪問,若是還未分配物理內存->
發生缺頁異常->
內核調用__alloc_pages爲進程分配物理頁框,並將物理內存和虛擬內存的映射關係寫入頁表