Linux核心常見分配函式

2021-06-28 04:46:52 字數 2259 閱讀 4008

1.      原理說明

linux核心中採用了一種同時適用於32位和64位系統的記憶體分頁模型,對於32位系統來說,兩級頁表足夠用了,而在x86_64系統中,用到了四級頁表,如圖2-1所示。四級頁表分別為:

l         頁全域性目錄(page global directory)

l         頁上級目錄(page upper directory)

l         頁中間目錄(page middle directory)

l         頁表(page table)

頁全域性目錄包含若干頁上級目錄的位址,頁上級目錄又依次包含若干頁中間目錄的位址,而頁中間目錄又包含若干頁表的位址,每乙個頁表項指向乙個頁框。linux中採用4kb大小的頁框作為標準的記憶體分配單元。

多級分頁目錄結構

1.1.      夥伴系統演算法

在實際應用中,經常需要分配一組連續的頁框,而頻繁地申請和釋放不同大小的連續頁框,必然導致在已分配頁框的記憶體塊中分散了許多小塊的空閒頁框。這樣,即使這些頁框是空閒的,其他需要分配連續頁框的應用也很難得到滿足。

為了避免出現這種情況,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個頁框的鍊錶查詢,如果仍然沒有,則返回錯誤。

頁框塊在釋放時,會主動將兩個連續的頁框塊合併為乙個較大的頁框塊。

1.2.      slab分配器

slab分配器源於 solaris 2.4 的分配演算法,工作於物理記憶體頁框分配器之上,管理特定大小物件的快取,進行快速而高效的記憶體分配。

slab分配器為每種使用的核心物件建立單獨的緩衝區。linux 核心已經採用了夥伴系統管理物理記憶體頁框,因此 slab分配器直接工作於夥伴系統之上。每種緩衝區由多個 slab 組成,每個 slab就是一組連續的物理記憶體頁框,被劃分成了固定數目的物件。根據物件大小的不同,預設情況下乙個 slab 最多可以由 1024個頁框構成。出於對齊等其它方面的要求,slab 中分配給物件的記憶體可能大於使用者要求的物件實際大小,這會造成一定的記憶體浪費。

2.      常用記憶體分配函式 

2.1.      __get_free_pages

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)

__get_free_pages函式是最原始的記憶體分配方式,直接從夥伴系統中獲取原始頁框,返回值為第乙個頁框的起始位址。__get_free_pages在實現上只是封裝了alloc_pages函式,從**分析,alloc_pages函式會分配長度為1《幾種分配函式的比較

分配原理

最大記憶體 其他

__get_free_pages

直接對頁框進行操作

4mb適用於分配較大量的連續物理記憶體

kmem_cache_alloc

基於slab機制實現

128kb

適合需要頻繁申請釋放相同大小記憶體塊時使用

kmalloc

基於kmem_cache_alloc實現

128kb

最常見的分配方式,需要小於頁框大小的記憶體時可以使用

vmalloc

建立非連續物理記憶體到虛擬位址的對映

物理不連續,適合需要大記憶體,但是對位址連續性沒有要求的場合

dma_alloc_coherent

基於__alloc_pages實現

4mb適用於dma操作

ioremap

實現已知實體地址到虛擬位址的對映

適用於實體地址已知的場合,如裝置驅動

alloc_bootmem

在啟動kernel時,預留一段記憶體,核心看不見

小於物理記憶體大小,記憶體管理要求較高

注:表中提到的最大記憶體資料來自centos5.3 x86_64系統,其他系統和體系結構會有不同

Linux核心中常見記憶體分配函式

linux核心中採用了一種同時適用於32位和64位系統的記憶體分頁模型,對於32位系統來說,兩級頁表足夠用了,而在x86 64系統中,用到了四級頁表,如圖2 1所示。四級頁表分別為 l 頁全域性目錄 page global directory l 頁上級目錄 page upper directory...

Linux核心中常見記憶體分配函式

linux核心中常見記憶體分配函式 linux核心中採用了一種同時適用於32位和64位系統的記憶體分頁模型,對於32位系統來說,兩級頁表足夠用了,而在x86 64系統中,用到了四級頁表,如圖2 1所示。四級頁表分別為 頁全域性目錄 page global directory 頁上級目錄 page u...

Linux核心中記憶體分配函式

1.原理說明 linux核心中採 用了一種同時適用於32位和64位系統的內 存分頁模型,對於32位系統來說,兩級頁表足夠用了,而在x86 64系 統中,用到了四級頁表,如圖2 1所示。四級頁表分別為 頁全域性目錄 page global directory 頁上級目錄 page upper dire...