自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

圖解Linux內(nèi)存管理:伙伴系統(tǒng)

系統(tǒng) Linux
伙伴系統(tǒng)是Linux內(nèi)存管理的一個重要機制,伙伴系統(tǒng)通過伙伴機制將小塊的內(nèi)存合并,在一定程度上減少了內(nèi)存碎片,同時也實現(xiàn)了分配連續(xù)物理內(nèi)存的功能。

大家好,這里是物聯(lián)網(wǎng)心球。

本文我們繼續(xù)來介紹Linux內(nèi)存管理,今天要講的是內(nèi)存管理中非常重要的機制伙伴系統(tǒng)。

為了小伙伴們能正確理解今天講的內(nèi)容,這里需要強調(diào)一下,我們今天還是圍繞物理內(nèi)存來講解,請不要和虛擬內(nèi)存弄混淆了。

1.伙伴系統(tǒng)是什么?

伙伴系統(tǒng)是一種內(nèi)存管理算法,用于動態(tài)分配和釋放物理內(nèi)存頁。

該算法的核心思想是將相鄰且大小相等的內(nèi)存頁合并成一個大的內(nèi)存頁,從而減少內(nèi)存碎片的產(chǎn)生和浪費。

在伙伴系統(tǒng)中,每個內(nèi)存頁都有一個伙伴,當(dāng)某個內(nèi)存頁被分配時,系統(tǒng)會查找它的伙伴,如果伙伴也未被分配,則將它們合并成一個更大的內(nèi)存頁。

反之,當(dāng)某個內(nèi)存頁被釋放時,系統(tǒng)會查找它的伙伴,如果伙伴也空閑,則將它們合并成一個更大的內(nèi)存頁。

圖片圖片

Linux通過幾個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)伙伴系統(tǒng):

  • pglist_data:表示內(nèi)存節(jié)點,內(nèi)存節(jié)點詳細(xì)介紹請參考文章圖解Linux內(nèi)存管理_整體架構(gòu)。
  • zone:表示內(nèi)存區(qū)域,常見的區(qū)域有ZONE_DMA,ZONE_DMA32,ZONE_NORMAL,ZONE_HIGHMEM,每個區(qū)域都對應(yīng)一個伙伴系統(tǒng)。
  • free_area:表示分配階級,總共有MAX_ORDER(通常為11)個分配階級,每個分配階級對應(yīng)的內(nèi)存塊大小為2^order個page。
  • free_list:表示頁類型鏈表頭,用于內(nèi)存碎片處理,本文不展開討論。

2.內(nèi)存管理區(qū)域

內(nèi)存管理區(qū)域是伙伴系統(tǒng)一個核心的概念,內(nèi)存節(jié)點被進(jìn)一步劃分成更小的內(nèi)存區(qū)域,這個更小的內(nèi)存區(qū)域稱為內(nèi)存管理區(qū)域(zone),zone的定義如下:

圖片圖片

2.1 為什么需要把內(nèi)存節(jié)點劃分成zone?

Linux系統(tǒng)不能把所有的內(nèi)存都按相同的方式去處理,所以把內(nèi)存節(jié)點劃分成不同的區(qū)域,實現(xiàn)內(nèi)存精細(xì)化管理,比如以下幾種情況,需要將物理內(nèi)存進(jìn)行區(qū)域劃分:

  • 舊的工業(yè)標(biāo)準(zhǔn)體系結(jié)構(gòu)(Industry Standard Architecture,ISA)總線只能直接訪問 16MB 以下的內(nèi)存,所以需要劃分一個ZONE_DMA區(qū)域來兼容ISA標(biāo)準(zhǔn)。
  • X86_32位系統(tǒng)內(nèi)核虛擬地址空間只有1GB,其中896MB空間已經(jīng)用于直接映射,剩余的128M空間需要訪問3GB的物理內(nèi)存空間,所以需要劃分ZONE_HIGHMEM高端內(nèi)存區(qū)域。

2.2 zone類型

zone主要可以劃分為如下幾種類型:

  • ZONE_DMA:直接內(nèi)存訪問,是一種允許某些硬件子系統(tǒng)(例如磁盤驅(qū)動器或顯卡)直接訪問系統(tǒng)內(nèi)存的技術(shù)。
  • ZONE_DMA32:在32位系統(tǒng)上實現(xiàn)DMA傳輸?shù)囊环N機制,主要用于允許64位或者大于16MB的DMA傳輸。
  • ZONE_NORMAL:在Linux內(nèi)存區(qū)域劃分中,表示正常的內(nèi)存區(qū)域,即不包含高端內(nèi)存的區(qū)域。
  • ZONE_HIGHMEM:在Linux內(nèi)存區(qū)域劃分中,表示高端內(nèi)存,即不常用的內(nèi)存區(qū)域,通常用于大型數(shù)據(jù)的緩存或者動態(tài)內(nèi)存分配。

Linux內(nèi)存節(jié)點并不一定會包含所有的內(nèi)存區(qū)域類型,多數(shù)情況是只包含部分區(qū)域類型,我們以X86_32和X86_64系統(tǒng)來講解。

X86_32系統(tǒng)物理內(nèi)存劃分如下:

圖片圖片

X86_32系統(tǒng)將物理內(nèi)存劃分為3個zone:

ZONE_DMA:0-16M,DMA內(nèi)存區(qū)域。

ZONE_NORMAL:16M-896M,普通內(nèi)存區(qū)域。

ZONE_HIGHMEM:896M-4GB,高端內(nèi)存只存在于32位系統(tǒng)。

X86_64系統(tǒng)物理內(nèi)存劃分如下:

圖片圖片

X86_64系統(tǒng)將物理內(nèi)存劃分為3個zone:

ZONE_DMA:0-16M,DMA內(nèi)存區(qū)域。

ZONE_DMA32:16M-4GB,DMA32內(nèi)存區(qū)域。

ZONE_NORMAL:4GB-end,普通內(nèi)存區(qū)域。

不同的CPU架構(gòu)和系統(tǒng)支持的內(nèi)存區(qū)域都會有差異,我們可以通過

dmesg | grep "mem"查看Linux系統(tǒng)內(nèi)存區(qū)域的詳細(xì)信息。

圖片圖片

3.伙伴系統(tǒng)初始化

Linux啟動時,伙伴系統(tǒng)并沒有實際物理內(nèi)存,內(nèi)核首先需要根據(jù)系統(tǒng)配置信息初始化各個內(nèi)存區(qū)域,接下來需要將memblock(早期內(nèi)存分配機制)模塊的內(nèi)存釋放至伙伴系統(tǒng),伙伴系統(tǒng)完成初始化后,memblock將退出歷史舞臺,后續(xù)的物理內(nèi)存分配和回收由伙伴系統(tǒng)來完成。

Linux伙伴系統(tǒng)初始化流程如下:

start_kernel()->mm_init()->mem_init()->memblock_free_all()。

Linux內(nèi)核獲取設(shè)備樹物理內(nèi)存信息初始化memblock,由memblock負(fù)責(zé)早期的內(nèi)存分配工作,memblock完成對應(yīng)的工作后,將未使用的內(nèi)存釋放至伙伴系統(tǒng),完成伙伴系統(tǒng)的初始化工作。

圖片圖片

4.伙伴系統(tǒng)內(nèi)存分配

伙伴系統(tǒng)常見的內(nèi)存分配函數(shù)如下:

圖片圖片

內(nèi)存分配函數(shù)需要傳入兩個參數(shù)gfp_mask和order。

  • gfp_mask:指定從哪個內(nèi)存區(qū)域分配內(nèi)存,內(nèi)存區(qū)域定義如下:

圖片圖片

  • order:指定分配階級。

調(diào)用內(nèi)存分配函數(shù)從伙伴系統(tǒng)分配內(nèi)存時,通過gfg_mask和order找到對應(yīng)的分配階級,并申請2^order個page的內(nèi)存塊。

此時會出現(xiàn)兩種情況:

  • 情況1:指定分配階級有空閑內(nèi)存塊。

該情況比較簡單,只需要把該內(nèi)存塊分配出去即可。

  • 情況2:指定分配階級沒有空閑內(nèi)存塊。

該情況處理起來會復(fù)雜一點,需要向高階分配階級申請空閑內(nèi)存塊,首先向order+1階申請空閑內(nèi)存塊,如果order+1階沒有空閑內(nèi)存塊,繼續(xù)向order+2階申請空閑內(nèi)存塊,以此類推直到在order+n階找到空閑內(nèi)存塊。

將order+n階空閑內(nèi)存塊減半分裂,其中一半插入上一階內(nèi)存鏈表,另外一半內(nèi)存塊繼續(xù)減半分裂,減半后其中一半內(nèi)存塊繼續(xù)插入對應(yīng)的分配階級內(nèi)存鏈表,另外一半內(nèi)存塊繼續(xù)減半分裂,直至內(nèi)存塊符合申請內(nèi)存塊大小。

圖片圖片

這里介紹一下伙伴系統(tǒng)調(diào)試小技巧,通過cat /proc/buddyinfo可以查看伙伴系統(tǒng)所有分配階級內(nèi)存塊情況。

圖片

5.伙伴系統(tǒng)內(nèi)存回收

伙伴系統(tǒng)內(nèi)存回收函數(shù)如下:

圖片圖片

調(diào)用內(nèi)存回收函數(shù)同樣需要指定order,指定order的目的是告知伙伴系統(tǒng)當(dāng)前回收的內(nèi)存塊包含2^order個page。

伙伴系統(tǒng)根據(jù)order找到對應(yīng)的分配階級,伙伴系統(tǒng)不會把回收的內(nèi)存塊直接插入內(nèi)存鏈表,而是先在分配階級內(nèi)存鏈表中查找內(nèi)存塊的伙伴。

如果沒有找到內(nèi)存塊的伙伴,則將內(nèi)存塊插入分配階級內(nèi)存鏈表。

如果找到內(nèi)存塊的伙伴,則將內(nèi)存塊和伙伴進(jìn)行合并,形成一個2倍大小的新的內(nèi)存塊,將新的內(nèi)存塊繼續(xù)插入下一個分配階級內(nèi)存鏈表,同時也需要判斷新的內(nèi)存塊是否存在伙伴,以此類推直到未找到內(nèi)存塊伙伴,并將合并后的內(nèi)存塊插入到最終分配階級內(nèi)存鏈表。

圖片圖片

總結(jié)

伙伴系統(tǒng)是Linux內(nèi)存管理的一個重要機制,伙伴系統(tǒng)通過伙伴機制將小塊的內(nèi)存合并,在一定程度上減少了內(nèi)存碎片,同時也實現(xiàn)了分配連續(xù)物理內(nèi)存的功能。

責(zé)任編輯:武曉燕 來源: 物聯(lián)網(wǎng)心球
相關(guān)推薦

2013-10-12 11:15:09

Linux運維內(nèi)存管理

2025-03-21 00:00:00

2021-09-05 18:29:58

Linux內(nèi)存回收

2013-10-11 17:32:18

Linux運維內(nèi)存管理

2021-04-12 05:44:44

Linux文件系統(tǒng)

2009-08-17 08:32:56

Linux操作系統(tǒng)內(nèi)存管理Linux

2022-01-26 00:10:00

Linux內(nèi)存磁盤

2023-10-18 13:31:00

Linux內(nèi)存

2022-08-08 08:31:00

Linux內(nèi)存管理

2017-05-18 16:30:29

Linux內(nèi)存管理

2025-01-13 00:30:17

2020-08-27 14:40:55

Linux內(nèi)存內(nèi)核

2009-12-25 17:15:03

Linux內(nèi)存

2020-07-28 08:10:33

Linux內(nèi)存虛擬

2009-12-25 15:24:16

內(nèi)存管理

2020-04-08 09:20:25

Linux內(nèi)存系統(tǒng)

2020-06-28 09:30:37

Linux內(nèi)存操作系統(tǒng)

2018-08-09 16:32:49

內(nèi)存管理框架

2022-02-11 07:45:10

Linuxsmem系統(tǒng)

2021-03-17 21:34:44

Linux內(nèi)存管理
點贊
收藏

51CTO技術(shù)棧公眾號