Linux內(nèi)存管理---伙伴堆算法

什么是伙伴堆算法

伙伴堆算法(也叫伙伴系統(tǒng)蝙昙,buddy system)是Linux系統(tǒng)中的一種動(dòng)態(tài)的內(nèi)存管理算法

伙伴堆算法的用途

每當(dāng)分配和釋放內(nèi)存的時(shí)候系統(tǒng)都將遇到尾部碎片的問題疏之,比如當(dāng)請(qǐng)求一個(gè)頁面的時(shí)候冀膝,即使系統(tǒng)可用頁面總數(shù)足夠多裂逐,但是無法分配大塊連續(xù)的頁面输涕。也就是說可用頁面會(huì)被一個(gè)或多個(gè)不連續(xù)的不可用頁面拆開展东。使用伙伴算法就可以一定程度解決這種頁面碎片的問題蜒滩。

算法基本思想

Linux把所有的空閑頁框分組為11個(gè)塊鏈表寄雀,每個(gè)鏈表上的頁框塊是固定的得滤。在第i條鏈表中每個(gè)頁框塊都包含2的i次方個(gè)連續(xù)頁,其中i稱為分配階盒犹。
下面以一個(gè)例子懂更,講述伙伴算法的思想:假設(shè)要申請(qǐng)一個(gè)256個(gè)頁,先從256個(gè)頁框的鏈表中查找空閑塊急膀,如果沒有沮协,就去512個(gè)頁框的鏈表中找,找到了則將頁框塊分為2個(gè)256個(gè)頁框的塊脖阵,一個(gè)分配給應(yīng)用皂股,另外一個(gè)移到256個(gè)頁框的鏈表中。如果512個(gè)頁框的鏈表中仍沒有空閑塊命黔,繼續(xù)向1024個(gè)頁框的鏈表查找呜呐。如果1024塊存在,則將其中的256頁框作為請(qǐng)求返回悍募,剩余的768分成256塊和512塊分別插到相應(yīng)的鏈表中蘑辑。如果仍然沒有,則返回錯(cuò)誤坠宴。

算法涉及的數(shù)據(jù)結(jié)構(gòu)

Linux中伙伴堆算法的核心數(shù)據(jù)結(jié)構(gòu)包含以下兩個(gè)部分

1.free_area

//在mmzone.h中
#define MAX_ORDER 11
   struct zone
{
  ... ...
  struct free_area free_area[MAX_ORDER]洋魂;
  ... ...
};

每個(gè)物理內(nèi)存節(jié)點(diǎn)上都可以劃分為不同的zone,劃分zone的原因是因?yàn)閄86的一些架構(gòu)的影響(這一部分不是本文關(guān)鍵)喜鼓,因此可以理解為zone就是一塊內(nèi)存的管理符副砍,其中有一個(gè)很重要的數(shù)據(jù)就是free_area,并且它是一個(gè)結(jié)構(gòu)體數(shù)組庄岖,具體定義如下豁翎。

//在mmzone.h中
struct free_area
{
  struct list_head free_list[MIGRATR_TYPES];//說明了頁的屬性
  unsigned long nr_free;//來說明每個(gè)界中有多少可用的頁
};

在這個(gè)結(jié)構(gòu)體中有兩個(gè)域,第一個(gè)是free_list隅忿,是個(gè)鏈表心剥,它表示的就是當(dāng)前分配階所對(duì)應(yīng)的頁框塊的鏈表邦尊。第二個(gè)nr_free指的是當(dāng)前鏈表中空閑頁框塊的數(shù)目,比如free_area[2]中nr_free的值為5优烧,表示有5個(gè)大小為4的頁框塊蝉揍,那么總的空閑頁為20.其具體結(jié)構(gòu)可見下面兩幅圖


zone+free_area.gif

這張圖很好的說明了zone的結(jié)構(gòu)體中包含以分free_area字段并且free_area是一個(gè)數(shù)組后面用鏈表的形式附加了各種大小的頁面對(duì)于zone中另一個(gè)比較重要的結(jié)構(gòu)mem_map結(jié)構(gòu)在稍后進(jìn)行說明。free_area的具體實(shí)現(xiàn)見下圖畦娄。


free_area2.png

對(duì)應(yīng)數(shù)組下標(biāo)為i的位置連接一些大小為2的i次冪大小的空閑頁面又沾,并通過雙向鏈表的形式組織起來,nr_free的值為鏈表中空閑頁面的個(gè)數(shù)熙卡。

2. zone_mem_map數(shù)組

zone_mem_map是用于查找連續(xù)伙伴空間用的伙伴位圖捍掺。用一位描述伙伴塊的狀態(tài)位碼,稱之為伙伴位碼再膳。比如,bit0為第0塊和第1塊的伙伴位碼曲横,如果bit0為1喂柒,表示這兩塊至少有一塊已經(jīng)分配出去,如果bit0為0禾嫉,說明兩塊都空閑灾杰,還沒分配。整個(gè)內(nèi)存釋放或者分配過程中熙参,位圖扮演了重要的角色艳吠。

內(nèi)存分配與釋放得原理

分配原理:假如系統(tǒng)需要4(2 * 2)個(gè)頁面大小的內(nèi)存塊,該算法就到free_area[2]中查找孽椰,如果鏈表中有空閑塊昭娩,就直接從中摘下并分配出去。如果沒有黍匾,算法將順著數(shù)組向上查找free_area[3],如果free_area[3]中有空閑塊栏渺,則將其從鏈表中摘下,分成等大小的兩部分锐涯,前四個(gè)頁面作為一個(gè)塊插入free_area[2]磕诊,后4個(gè)頁面分配出去,free_area[3]中也沒有纹腌,就再向上查找霎终,如果free_area[4]中有,就將這16(2 * 2 * 2 * 2)個(gè)頁面等分成兩份升薯,前一半掛如free_area[3]的鏈表頭部莱褒,后一半的8個(gè)頁等分成兩等分,前一半掛free_area[2]的鏈表中覆劈,后一半分配出去保礼。假如free_area[4]也沒有沛励,則重復(fù)上面的過程,知道到達(dá)free_area數(shù)組的最后炮障,如果還沒有則放棄分配目派。

釋放原理:內(nèi)存的釋放是分配的逆過程,也可以看作是伙伴的合并過程胁赢。當(dāng)釋放一個(gè)塊時(shí)企蹭,先在其對(duì)應(yīng)的鏈表中考查是否有伙伴存在,如果沒有伙伴塊智末,就直接把要釋放的塊掛入鏈表頭谅摄;如果有,則從鏈表中摘下伙伴系馆,合并成一個(gè)大塊送漠,然后繼續(xù)考察合并后的塊在更大一級(jí)鏈表中是否有伙伴存在,直到不能合并或者已經(jīng)合并到了最大的塊(2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2個(gè)頁面)由蘑。整個(gè)過程中闽寡,位圖扮演了重要的角色,位圖的某一位對(duì)應(yīng)兩個(gè)互為伙伴的塊尼酿,為1表示其中一塊已經(jīng)分配出去了爷狈,為0表示兩塊都空閑∩亚妫伙伴中無論是分配還是釋放都只是相對(duì)的位圖進(jìn)行異或操作涎永。分配內(nèi)存時(shí)對(duì)位圖的是為釋放過程服務(wù),釋放過程根據(jù)位圖判斷伙伴是否存在鹿响,如果對(duì)相應(yīng)位的異或操作得1羡微,則沒有伙伴可以合并,如果異或操作得0抢野,就進(jìn)行合并拷淘,并且繼續(xù)按這種方式合并伙伴,直到不能合并為止指孤。

內(nèi)存分配與釋放的例子

下面通過一個(gè)例子启涯,來深入地理解一下伙伴算法的真正內(nèi)涵(下面這個(gè)例子并不嚴(yán)格表示Linux 內(nèi)核中的實(shí)現(xiàn),是闡述伙伴算法的實(shí)現(xiàn)思想):
假設(shè)系統(tǒng)中有 1MB 大小的內(nèi)存需要?jiǎng)討B(tài)管理恃轩,按照伙伴算法的要求:需要將這1M大小的內(nèi)存進(jìn)行劃分结洼。這里,我們將這1M的內(nèi)存分為 64K叉跛、64K松忍、128K、256K筷厘、和512K 共五個(gè)部分鸣峭,如下圖 a 所示


伙伴堆.jpg

1.此時(shí)宏所,如果有一個(gè)程序A想要申請(qǐng)一塊45K大小的內(nèi)存,則系統(tǒng)會(huì)將第一塊64K的內(nèi)存塊分配給該程序(產(chǎn)生內(nèi)部碎片為代價(jià))摊溶,如圖b所示爬骤;

2.然后程序B向系統(tǒng)申請(qǐng)一塊68K大小的內(nèi)存,系統(tǒng)會(huì)將128K內(nèi)存分配給該程序莫换,如圖c所示霞玄;

3.接下來,程序C要申請(qǐng)一塊大小為35K的內(nèi)存拉岁。系統(tǒng)將空閑的64K內(nèi)存分配給該程序坷剧,如圖d所示;

4.之后程序D需要一塊大小為90K的內(nèi)存喊暖。當(dāng)程序提出申請(qǐng)時(shí)惫企,系統(tǒng)本該分配給程序D一塊128K大小的內(nèi)存,但此時(shí)內(nèi)存中已經(jīng)沒有空閑的128K內(nèi)存塊了陵叽,于是根據(jù)伙伴算法的原理雅任,系統(tǒng)會(huì)將256K大小的內(nèi)存塊平分,將其中一塊分配給程序D咨跌,另一塊作為空閑內(nèi)存塊保留,等待以后使用硼婿,如圖e所示锌半;

5.緊接著,程序C釋放了它申請(qǐng)的64K內(nèi)存寇漫。在內(nèi)存釋放的同時(shí)刊殉,系統(tǒng)還負(fù)責(zé)檢查與之相鄰并且同樣大小的內(nèi)存是否也空閑,由于此時(shí)程序A并沒有釋放它的內(nèi)存州胳,所以系統(tǒng)只會(huì)將程序C的64K內(nèi)存回收记焊,如圖f所示;

6.然后程序A也釋放掉由它申請(qǐng)的64K內(nèi)存栓撞,系統(tǒng)隨機(jī)發(fā)現(xiàn)與之相鄰且大小相同的一段內(nèi)存塊恰好也處于空閑狀態(tài)遍膜。于是,將兩者合并成128K內(nèi)存瓤湘,如圖g所示瓢颅;

7.之后程序B釋放掉它的128k,系統(tǒng)也將這塊內(nèi)存與相鄰的128K內(nèi)存合并成256K的空閑內(nèi)存弛说,如圖h所示挽懦;

8.最后程序D也釋放掉它的內(nèi)存,經(jīng)過三次合并后木人,系統(tǒng)得到了一塊1024K的完整內(nèi)存信柿,如圖i所示冀偶。

buddy算法的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

1.解決內(nèi)存碎片問題

2.避免把內(nèi)存拆得太碎得同時(shí),使內(nèi)存的分配和釋放過程迅速

缺點(diǎn)

1.雖然解決了內(nèi)存碎片問題渔嚷,但是該算法中进鸠,一個(gè)很小的塊往往會(huì)阻礙一個(gè)大塊的合并。(一片內(nèi)存中僅一個(gè)小的內(nèi)存塊沒有釋放圃伶,旁邊兩個(gè)大的就不能合并堤如。)

2.算法中有一定的浪費(fèi)現(xiàn)象,伙伴算法是按2的冪次方大小進(jìn)行分配內(nèi)存塊窒朋。

3.另外拆分和合并涉及到 較多的鏈表和位圖操作搀罢,開銷還是比較大的。

reference

[1].https://www.cnblogs.com/alantu2018/p/8527821.html
[2].https://www.cnblogs.com/cherishui/p/4246133.html
[3].https://blog.csdn.net/yq272393925/article/details/89286963
[4].https://www.cnblogs.com/huhuuu/p/3598760.html
[5].https://blog.csdn.net/qq_22238021/article/details/80208630

總結(jié)
文章寫的并不全侥猩,包括位圖具體得算法榔至,linux內(nèi)存池中的具體實(shí)現(xiàn)也都暫時(shí)沒看完,以及優(yōu)缺點(diǎn)總結(jié)并不全面欺劳。水平有限唧取,暫時(shí)也就先這樣吧。等我啥時(shí)候明白了我再更好了划提。Linux這種東西還是要多看幾遍得

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枫弟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鹏往,更是在濱河造成了極大的恐慌淡诗,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伊履,死亡現(xiàn)場(chǎng)離奇詭異韩容,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)唐瀑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門群凶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哄辣,你說我怎么就攤上這事请梢。” “怎么了力穗?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵溢陪,是天一觀的道長。 經(jīng)常有香客問我睛廊,道長形真,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮咆霜,結(jié)果婚禮上邓馒,老公的妹妹穿的比我還像新娘。我一直安慰自己蛾坯,他們只是感情好光酣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著脉课,像睡著了一般救军。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上倘零,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天唱遭,我揣著相機(jī)與錄音,去河邊找鬼呈驶。 笑死拷泽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的袖瞻。 我是一名探鬼主播司致,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼聋迎!你這毒婦竟也來了脂矫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤霉晕,失蹤者是張志新(化名)和其女友劉穎羹唠,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娄昆,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年缝彬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了萌焰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谷浅,死狀恐怖扒俯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情一疯,我是刑警寧澤撼玄,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站墩邀,受9級(jí)特大地震影響掌猛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜眉睹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一荔茬、第九天 我趴在偏房一處隱蔽的房頂上張望废膘。 院中可真熱鬧,春花似錦慕蔚、人聲如沸丐黄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灌闺。三九已至,卻和暖如春坏瞄,著一層夾襖步出監(jiān)牢的瞬間桂对,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工惦积, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留接校,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓狮崩,卻偏偏與公主長得像蛛勉,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子睦柴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1 內(nèi)存尋址 1.1 物理地址诽凌、虛擬地址以及線性地址 物理地址: 物理內(nèi)存的內(nèi)存單元地址 虛擬地址: 程序員看到的...
    瘋狂小王子閱讀 2,816評(píng)論 3 21
  • Linux 內(nèi)存管理 1 頁的概念 linux 內(nèi)核中把物理頁作為內(nèi)存分配的最小單位,32位CPU 頁的大小通常為...
    赤兔歡閱讀 3,275評(píng)論 0 5
  • 抓主線坦敌,三個(gè)點(diǎn): 虛擬內(nèi)存組織 虛擬內(nèi)存和物理內(nèi)存的轉(zhuǎn)換 物理內(nèi)存組織 虛擬內(nèi)存組織 平時(shí)在進(jìn)程中侣诵,所謂的內(nèi)存地址...
    123archu閱讀 3,203評(píng)論 1 7
  • Linux的物理地址一直深受碎片化的困擾。 1狱窘、什么是碎片化杜顺? 用戶頻繁地請(qǐng)求和釋放不同大小的一組連續(xù)頁框,必然導(dǎo)...
    senpaiLi閱讀 2,306評(píng)論 0 7
  • 詳細(xì)內(nèi)容歡迎跳轉(zhuǎn) : https://aiden-dong.gitee.io/2019/05/06/Linux%E...
    陌城小川閱讀 976評(píng)論 0 0