內核內存管理總結
內核的內存分配不同於用戶空間的內存分配,,balabala
內核裏內存的分配主要有這麼幾種,首先是按頁來請求內存,用alloc_pages()和它的幾個兄弟函數可以實現,按頁分配,即直接請求返回的是一個或者多個頁框;而對於頁框的管理,內存中不同頁會被分爲不同zones,區分標準是:比如DMA能直接操作的區域,HIGH memory區域(後面再講),每個不同的區域分別讓buddy system algorithm來接管分配,buddy system algorithm,即把頁分爲不同大小的block,每個block分別包含頁數目,1,2,4直到1024;
使用這buddy system algorithm而不是普通的鏈表一樣的管理是爲了防止分頁的外部碎片,而導致大的內存allocation請求卻因內存的不連續即碎片原因而無法請求成功
而對於某些操作,4KB的頁(64位是8KB)分配還是太大了,這些請求會另外用kalloc()來實現,kalloc會返回大於申請空間的物理上連續的內存,這種內存分配是最常見的,很明顯kalloc也要解決外部碎片的問題,這裏是通過slab layer中維護一個cache來實現的,cache中有malloc_size表,指向26個大小是32,64一直到131072大小的區域的相關結構(cache descriptor),它防止碎片的方法與buddy system algorithm幾乎一樣,這裏可以想象一下如果不用slab layer來維護而是用free list會有什麼壞處(當然是外部碎片啦)
而這裏的slab layer其實不止這一種cache(要區分開CPU的高速緩存),slab layer還有其他cache是專門存儲其他slab的,slab裏有若干段連續的內存空間用來分配給固定object,這裏就要引出另一種內存分配方式,是給那些大量創建刪除的對象,很容易想到,文件系統的inode和進程的process descriptor都是這種類型的,這裏的slab像是一個內存池,不會主動去釋放裏面的內存空間,而是像內存池一樣,要用到再取出,這裏取出的方式也有講究,優先把沒被用光的取出,沒有再去找新的沒用過的空間
最後再介紹一種vmalloc,這種是返回邏輯上連續的而物理空間不連續的空間,較爲少用
TODO
-
內核分配的冷熱區域
-
uderstanding linux kernel323頁末說的從buddy system的內部碎片free list會拿來幹嘛用
參考資料
-
understanding the linux kernel
-
Linux Kernel Development
TODO
-
APUE的slab