Linux夥伴演算法

2021-07-03 04:13:02 字數 3572 閱讀 8310

最近

一由於筆者能力有限,文中難免存在不足,如果發現錯誤之處,希望能幫助我及時糾正錯誤之處。

1、夥伴演算法的用途

管理物理記憶體,解決外碎片問題。

2、滿足以下條件的兩個塊稱為夥伴

l 兩個塊具有相同的大小,記作b l 

它們的實體地址是連續的 l 

第一塊的第乙個頁框的實體地址是2*b*2^12

的倍數

3、夥伴演算法管理結構

夥伴演算法把物理記憶體分為11

個組,第0、

1、...10組分別包含

2^0、

2^1、

...2^10個連續物理頁面的記憶體。在

zone

結構中,有乙個

free_area

#define max_order 11

struct zone 

struct free_area ;

由此可知夥伴演算法管理結構如下圖所示:

4、夥伴演算法的初始化和釋放

1)夥伴演算法初始化過程

在start_kernel->

mem_init-> 

free_all_bootmem_node->

free_all_bootmem_core->

__free_pages_bootmem->

__free_pages->

__free_pages_ok->

free_one_page->

__free_one_page函式中,通過對每乙個頁面進行釋放,從而完成對夥伴演算法的初始化工作。

2)夥伴演算法的具體釋放過程

l 夥伴演算法釋放的思想

當釋放2^order

頁大小記憶體時,檢視它的夥伴是否空閒,如果空閒就將夥伴從該組鍊錶中刪除,並且將這兩個空閒的夥伴記憶體區域合併成乙個更高階的空閒記憶體區域,依次這樣操作下去。 l 

__free_one_page函式分析如下

static inline void __free_one_page(struct page *page,

struct zone *zone, unsigned int order)

set_page_order(page, order);

list_add(&page->lru,

&zone->free_area[order].free_list[migratetype]);

zone->free_area[order].nr_free++; }

5、夥伴演算法的記憶體分配

1)夥伴演算法記憶體分配的過程

當核心收到alloc_pages

系列函式的分配請求時,首先需要確定是從哪乙個節點上分配,然後再確定需要從節點的哪乙個

zone

上分配,最後再根據夥伴演算法,確定從

zone

的哪乙個

free_area

陣列成員上分配。在記憶體不足的情況下,還要**記憶體,如果記憶體還是不夠,還要排程

kswapd

把必要的記憶體儲存到交換分割槽中。記憶體分配模組總是試圖從代價最小的節點上分配,而對

zone

的確定則根據

alloc_pages()

系列函式的

gfp_mask

用以下規則確定: l 

如果gfp_mask

引數設定了

__gfp_dma

位,則只能從

zone_dma

中分配。 l 

如果gfp_mask

引數設定了

__gfp_highmem

位,則能夠從

zone_dma

、zone_normal

、zone__highmem

中分配。 l 

如果__gfp_dma

和__gfp_highmem

都沒有設定,則能夠從

zone_dma

和zone_normal

中分配。

當然,如果沒有指定__gfp_dma

標誌,則會盡量避免使用

zone_dma

區的記憶體,只有當指定的區記憶體不足,而

zone_dma

區又有充足的記憶體時,才會從

zone_dma

中分配。

2)夥伴演算法的具體記憶體分配過程

l 夥伴演算法記憶體分配的思想

舉例說明:假設請求分配4

個頁面,根據該演算法先到第

2(2^2=4)

個組中尋找空閒塊,如果該組沒有空閒塊就到第

3(2^3=8)

個組中尋找,假設在第

3個組中找到空閒塊,就把其中的

4個頁面分配出去,剩餘的

4個頁面放到第

2個組中。如果第三個組還是沒有空閒塊,就到第

4(2^4=16)

個組中尋找,如果在該組中找到空閒塊,把其中的

4個頁面分配出去,剩餘的

12個頁面被分成兩部分,其中的

8個頁面放到第

3個組,另外

4個頁面放到第2個組

...依次類推。 l 

alloc_pages系列函式最終會呼叫

__rmqueue

函式從free_area

中取出記憶體頁面,

__rmqueue

函式具體分析如下:

//返回申請到的記憶體空間首頁的

struct page

結構指標

static struct page *__rmqueue(struct zone *zone, unsigned int order)

return null; }

這個函式根據order

從最合適的

free_area

佇列中分配,如果不成功就從更大的塊中找,找到乙個合適的塊後把它摘下來,最後需要把大塊剩餘的那一部分分解並放到對應的佇列中去,這個工作是

expand

函式完成的。

linux夥伴演算法

它要解決的問題是頻繁地請求和釋放不同大小的一組連續頁框,必然導致在已分配頁框的塊內分散了許多小塊的空閒頁面,由此帶來的問題是,即使有足夠的空閒頁框可以滿足請求,但要分配乙個大塊的連續頁框可能無法滿足請求。夥伴演算法 buddy system 把所有的空閒頁框分為11個塊鍊錶,每塊鍊錶中分布包含特定的...

linux記憶體管理 夥伴系統演算法

分配記憶體 釋放記憶體 兩個塊的大小相同 兩個塊的位址連續 兩個塊必須是從同乙個大塊分離出來的 linux把每個zone分成max order個free area,每個free are的大小是2的冪次方。max order的值為11,第0組大小為2 0個頁,第1組大小為2 1個頁,依次類推,最大的是...

夥伴系統演算法

如有問題,歡迎一起討論 struct free area static struct page rmqueue struct zone zone,unsigned int order return null define mark used index,order,area change bit i...