夥伴系統與slab slub分配器

2021-08-21 21:32:15 字數 1472 閱讀 4299

記憶體管理有兩個演算法:夥伴演算法和slab/slub演算法。夥伴演算法是以頁為單位管理記憶體,slab演算法是以位元組為單位管理記憶體,是核心的小記憶體管理演算法。slab分配器並沒有脫離夥伴系統,而是基於夥伴系統分配的大記憶體進一步細分成小記憶體。先講夥伴系統,再講slab分配器。

夥伴系統是基於bootmem機制來分配一些資料結構的。bootmem初始化的時候會呼叫free_area_init_node來對記憶體域zone資料結構進行初始化。zone包含乙個frea_area的結構體來描述本zone的空閒頁塊鍊錶,也會在bootmem初始化zone時被一併初始化。

struct zone ____cacheline_internodealigned_in_smp;

注意struct free_area free_area[max_order]是乙個以煉表為元素的陣列,陣列的每個元素都是某個階數的空閒記憶體塊的鍊錶。

max_order(最大階數)一般預設為11,代表有11個free_area,即有11組空閒頁塊的鍊錶。

例如free_area[0]:是乙個鍊錶,該煉表裡是長度為1的頁塊。即這個煉表裡有若干記憶體塊,每個記憶體塊都是1個page。

free_area[10]:也是乙個鍊錶,該煉表裡是長度為1024的頁塊。即這個煉表裡有若干記憶體塊,每個記憶體塊都是1024個page(4m記憶體空間)。

free_area的下標與該元素的鍊錶中的記憶體塊大小存在2的階的關係。

那麼什麼是夥伴呢?如果同乙個鍊錶中的兩個頁塊滿足下面這三個條件,我們就稱這兩個頁塊為夥伴:

1)  兩個塊的大小相同,假設為b。

2)  兩個塊的實體地址連續。

3) 夥伴中第乙個塊的起始實體地址是2*b*page_size的整數倍。即第0塊和第1塊是夥伴,第2塊和第3塊是夥伴,但是第1塊和第2塊不是夥伴。這樣規定的目的是確保一對夥伴中的兩個塊可以合併成更高一級的大塊。

夥伴的關係有三種,(1)乙個被分配時,那麼另乙個就等著這個分配出去的塊被釋放後合併,然後遞迴的進行更大order的合併;(2)如果兩個都被分配,那麼肯定有乙個先被釋放,那麼化為情況一,注意在等待夥伴被釋放的同時,該塊可以被分配,從而情況一化為情況二,但是最終它們結果總是趨向於情況三,也就是都被釋放從而被合併然後插入到更大一層的鍊錶中。——有效防止記憶體碎片的產生。

如果鍊錶的階數為n,頁塊1的頁號為page_id,其夥伴的頁號查詢公式為:

buddy_id = page_id ^ (1 << n)

夥伴系統申請核心記憶體的介面有:alloc_pages,_ _get_free_pages等。

slub分配的原理可參考如下文章:

我們在驅動開發的時候經常用到kmalloc函式,它就是基於slab分配器實現的。例如,我們分配乙個17bytes的記憶體,會這樣呼叫:kmalloc(17, gfp_kernel),系統會從名稱「kmalloc-32」管理的slab快取池中分配乙個物件,即使浪費了剩餘的15byte。

夥伴系統(演算法) 記憶體分配技術(2)

記憶體管理中的分割槽分配方法 1 夥伴系統 演算法 記憶體分配技術 2 分配核心記憶體 buddy系統和slab系統 3 靜態分割槽方案受固定活躍程序數的限制,並且空間的使用也可能不是最優的。夥伴系統是乙個記憶體分配與管理演算法,該演算法管理的記憶體以2的冪次增長。假設記憶體大小是2,假設需求s大小...

夥伴系統演算法

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

Linux夥伴系統

夥伴系統的概述 linux核心記憶體管理的一項重要工作就是如何在頻繁申請釋放記憶體的情況下,避免碎片的產生。linux採用夥伴系統解決外部碎片的問題,採用slab解決內部碎片的問題,在這裡我們先討論外部碎片問題。避免外部碎片的方法有兩種 一種是之前介紹過的利用非連續記憶體的分配 另外一種則是用一種有...