日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文出現(xiàn)的內(nèi)核代碼來自linux4.19,如果有興趣,讀者可以配合代碼閱讀本文。

一、Linux物理內(nèi)存外碎片化概述

什么是Linux物理內(nèi)存碎片化?Linux物理內(nèi)存碎片化包括兩種:

1.物理內(nèi)存內(nèi)碎片:指分配給用戶的內(nèi)存空間中未被使用的部分。

例如進程需要使用3K bytes物理內(nèi)存,于是向系統(tǒng)申請了大小等于3Kbytes的內(nèi)存,但是由于Linux內(nèi)核伙伴系統(tǒng)算法最小顆粒是4K bytes,所以分配的是4Kbytes內(nèi)存,那么其中1K bytes未被使用的內(nèi)存就是內(nèi)存內(nèi)碎片。

Linux 物理內(nèi)存外碎片化淺析

 

Linux物理內(nèi)存內(nèi)碎片

2.物理內(nèi)存外碎片化:指系統(tǒng)中無法利用的小內(nèi)存塊。

例如系統(tǒng)剩余內(nèi)存為16K bytes,但是這16K bytes內(nèi)存是由4個4K bytes的頁面組成,即16K內(nèi)存物理頁幀號#1不連續(xù)。在系統(tǒng)剩余16K bytes內(nèi)存的情況下,系統(tǒng)卻無法成功分配大于4K的連續(xù)物理內(nèi)存,該情況就是內(nèi)存外碎片導致,本文中闡述的就是物理內(nèi)存外碎片化。

注:#1物理頁幀號:Linux物理內(nèi)存是通過頁面進行管理,并對每個頁面進行編號,稱為頁幀號,如果是連續(xù)的兩個物理頁面,其頁幀號是連續(xù)的。

Linux 物理內(nèi)存外碎片化淺析

 

Linux物理內(nèi)存外碎片

二、Linux物理內(nèi)存管理框架

闡述物理內(nèi)存外碎片化的來龍去脈前,先得明白Linux是如何管理物理內(nèi)存的?Linux內(nèi)核采用的是buddy system allocation,即著名的伙伴系統(tǒng)分配器。

1.設(shè)計思路

伙伴系統(tǒng)分配器的核心思路:將系統(tǒng)的空閑頁面分為11個塊鏈表,每個塊鏈表分別管理著1,2,4,8,16,32,64,128,256,512和1024個物理頁幀號連續(xù)的頁面。每個頁面大小為4K bytes,buddy管理的塊大小范圍從4K bytes到4M bytes,以2的倍數(shù)遞增。

Linux 物理內(nèi)存外碎片化淺析

 

Linux物理內(nèi)存管理框架圖

2.管理邏輯

Linux對物理頁面管理的框架如上圖,由于本文闡述的是物理內(nèi)存外碎片,所以關(guān)于伙伴系統(tǒng)本文只做簡單分析,不涉及具體的細節(jié)并不闡述關(guān)于per cpu pageset等內(nèi)容,如果讀者有興趣,可以參考內(nèi)核源碼。

Linux將物理內(nèi)存分為不同的node和zone來管理:

  • node:為了支持NUMA結(jié)構(gòu),即CPU對不同內(nèi)存簇的訪問速度不同,Linux設(shè)計了node結(jié)構(gòu),將物理內(nèi)存分為多個內(nèi)存節(jié)點管理;對于UMA結(jié)構(gòu),只有一個node節(jié)點。
  • zone:為兼容不同的平臺的硬件限制,例如80x86的體系結(jié)構(gòu)的硬件總線訪問等問題,Linux將node節(jié)點下的內(nèi)存分為多個zone;目前在ARM平臺,多個zone管理已非必要。

zone管理單元下的內(nèi)存通過free_area數(shù)組將內(nèi)存分成11個塊鏈表進行管理:

Linux 物理內(nèi)存外碎片化淺析

 

free_area數(shù)組總共有11個索引,每個索引管理著不同大小的塊鏈表。

  • free_area[0]管理的內(nèi)存單位為2^0頁面,即4K byte內(nèi)存;
  • free_area[1]管理的內(nèi)存單位為2^1的物理頁幀號連續(xù)頁面,即8K bytes內(nèi)存;
  • 以此類推;

free_area管理的內(nèi)存還細分為各種類型,例如不可移動頁面和可移動頁面等,每種類型的頁面類型對應(yīng)一個free_list鏈表,該鏈表就鏈接著頁面結(jié)構(gòu)體。

Linux 物理內(nèi)存外碎片化淺析

 

當分配頁面時,伙伴系統(tǒng)拿頁面的步驟如下:(不考慮內(nèi)存慢速路徑)

  • 根據(jù)分配頁面類型,找到對應(yīng)的內(nèi)存節(jié)點node和內(nèi)存管理單元zone;
  • 根據(jù)分配頁面大小,找到的對應(yīng)大小的free_area結(jié)構(gòu)體;
  • 根據(jù)分配頁面類型,找到對應(yīng)的free_list鏈表,分配頁面;

當向伙伴系統(tǒng)釋放頁面時,buddy釋放頁面的步驟如下:

  • 根據(jù)分配頁面類型,找到對應(yīng)的內(nèi)存節(jié)點node和內(nèi)存管理單元zone;
  • 判斷是否有物理頁幀號相連的空閑內(nèi)存塊,可以跟被釋放的內(nèi)存塊合并成更大的塊內(nèi)存,合并的條件:
  • 物理幀必須都是連續(xù)的;
  • 相同的類型和相同的大小;
  • 合并后塊內(nèi)存的第一個頁面的物理地址滿足”2*塊大小*4K”的倍數(shù)。
  • 根據(jù)釋放頁面的大小或者合并的大小,找到的對應(yīng)大小的free_area結(jié)構(gòu)體;
  • 根據(jù)釋放頁面的類型,找到對應(yīng)的free_list鏈表,釋放頁面;

三、Linux針對物理內(nèi)存外碎片化的措施

從“二、Linux物理內(nèi)存管理架構(gòu)”,可以發(fā)現(xiàn)伙伴系統(tǒng)內(nèi)存管理框架是可以有效改善物理內(nèi)存外碎片的,因為伙伴系統(tǒng)有如下兩個管理邏輯,可以減少了外碎片化的產(chǎn)生:

  • 小塊內(nèi)存在小塊鏈表分配,減少大塊鏈表被污染的概率;
  • 內(nèi)存釋放時會嘗試整合成大塊內(nèi)存的邏輯,有助于大塊內(nèi)存的合成;

除此之外,內(nèi)核還支持以下措施改善物理內(nèi)存外碎片化(只列舉主要的機制):

1.memory compaction

(1)內(nèi)存規(guī)整原理

Linux物理頁面規(guī)整機制,類似于磁盤整理,主要是應(yīng)用了內(nèi)核的頁面遷移機制,是一種將可移動頁面進行遷移后騰出連續(xù)物理內(nèi)存的方法。

假設(shè)存在一個非常小的內(nèi)存域如下:

Linux 物理內(nèi)存外碎片化淺析

 

藍色表示空閑的頁面,白色表示已經(jīng)被分配的頁面,可以看到如上內(nèi)存域的空閑頁面(藍色)非常零散,無法分配大于兩頁的連續(xù)物理內(nèi)存。

下面演示一下內(nèi)存規(guī)整的簡化工作原理,內(nèi)核會運行兩個獨立的掃描動作:第一個掃描從內(nèi)存域的底部開始,一邊掃描一邊將已分配的可移動(MOVABLE)頁面記錄到一個列表中:

Linux 物理內(nèi)存外碎片化淺析

 

另外第二掃描是從內(nèi)存域的頂部開始,掃描可以作為頁面遷移目標的空閑頁面位置,然后也記錄到一個列表里面:

Linux 物理內(nèi)存外碎片化淺析

 

等兩個掃描在域中間相遇,意味著掃描結(jié)束,然后將左邊掃描得到的已分配的頁面遷移到右邊空閑的頁面中,左邊就形成了一段連續(xù)的物理內(nèi)存,完成頁面規(guī)整。

Linux 物理內(nèi)存外碎片化淺析

 

(2)使用方法

如果想打開內(nèi)存規(guī)整,內(nèi)核需要打開相關(guān)的配置(默認為y)

Linux 物理內(nèi)存外碎片化淺析

 

打開如上配置后,內(nèi)存規(guī)整的觸發(fā)是自動的,觸發(fā)內(nèi)存規(guī)整的途徑如下:當進程嘗試分配高階內(nèi)存無法滿足并且完成direct_reclaim#1(暫不分析costly_order情況)后,系統(tǒng)會根據(jù)內(nèi)存剩余判斷是否觸發(fā)內(nèi)存規(guī)整;

注:#1direct_reclaim:進程分配內(nèi)存時發(fā)現(xiàn)內(nèi)存不足從而啟動直接回收內(nèi)存操作,這種模式下分配和回收是同步的關(guān)系,也就是說分配內(nèi)存的進程會因為等待內(nèi)存回收而被阻塞。

Linux 物理內(nèi)存外碎片化淺析

 

內(nèi)核也提供了接口給用戶觸發(fā)規(guī)整動作,接口如下:

/proc/sys/vm/compact_memory

只要往這個節(jié)點寫值即可觸發(fā)對系統(tǒng)所有node管理的內(nèi)存做內(nèi)存規(guī)整。

2.kcompactd

(1)kcompact設(shè)計原理

kcompactd是一個內(nèi)核規(guī)整的后臺進程,它跟memory compaction的區(qū)別在于:

memory compaction的觸發(fā)途徑是內(nèi)存分配進入direct_reclaim(暫不分析costly_order情況)后系統(tǒng)會根據(jù)內(nèi)存剩余判斷是否觸發(fā)內(nèi)存規(guī)整,或者用戶手動觸發(fā);

kcompactd在喚醒kswapd或者kswapd進入休眠時,主動觸發(fā)內(nèi)存規(guī)整。

kcompactd的觸發(fā)路徑如下:主要有如下兩個途徑:

喚醒kswapd之前觸發(fā)規(guī)整,觸發(fā)的條件是:本次分配不支持direct_reclaim,node內(nèi)存節(jié)點是平衡的,并且kswapd失敗的次數(shù)大于MAX_RECLAIM_RETRIES(默認16)。

Linux 物理內(nèi)存外碎片化淺析

 

kswapd即將進入睡眠時:

Linux 物理內(nèi)存外碎片化淺析

 

(2)使用方法

如果想打開內(nèi)存規(guī)整,內(nèi)核需要打開相關(guān)的配置(默認為y)

Linux 物理內(nèi)存外碎片化淺析

 

3.其他優(yōu)化的思路

內(nèi)核經(jīng)過不斷的優(yōu)化,那為何Linux為何還有物理內(nèi)存外碎片化呢?那是因為物理內(nèi)存外碎片化雖然是可以不斷優(yōu)化的,但卻無法得到根除。目前的內(nèi)核,我覺得導致物理外碎片化還有以下兩個主要原因:

  • 不可移動頁面污染了內(nèi)存環(huán)境,導致頁面規(guī)整失敗;
  • 隨著系統(tǒng)不斷申請和釋放的頁面,導致伙伴系統(tǒng)分配的物理內(nèi)存頁幀號越發(fā)隨機,從而導致內(nèi)存被隔斷的概率越高,碎片化的程度越高,在3.2闡述。

針對以上兩個原因,以下的優(yōu)化措施可能達到一定的優(yōu)化效果:

(1)減少UNMOVABLE頁面污染內(nèi)存環(huán)境

  • 限制不可以移動頁面偷頁行為

Linux內(nèi)存分配中支持fallback機制,又叫偷頁機制。該機制是為了規(guī)避同個zone管理單位頁面類型剩余不平衡的問題,例如同個zone,A頁面類型空閑內(nèi)存較多,B頁面類型空閑內(nèi)存卻非常緊缺,如果沒有偷頁機制,分配B頁面類型就會進入內(nèi)存分配慢速路徑。有了偷頁機制,在同個zone管理單位,如果UNMOVABLE類型無空閑頁面,但是MOVABLE類型頁面還有空閑頁面,偷頁機制支持在list_head[UNMOVABLE]分配不到頁面的情況下,向list_head[MOVABLE]分配頁面。

以下數(shù)組明確了各種頁面類型可偷的頁面類型,例如第一行表示UNMOVABLE頁面可以偷RECLAIMABLE和MOVABLE類型的頁面,其他類似。

Linux 物理內(nèi)存外碎片化淺析

 

如果不可移動頁面頻繁的偷頁會導致不可移動頁面很快污染了內(nèi)存環(huán)境,特別污染了可移動頁面的內(nèi)存,對內(nèi)存規(guī)整成功率的影響比較大。基于以上情況,可以在偷頁的機制上加上分配大小限制的判斷,不可移動頁面只有大塊內(nèi)存分配才允許偷頁,以此減少不可移動頁面對內(nèi)存環(huán)境的污染。

  • 不可移動類型頁面偷頁后主動償還

該方法主要是不可移動頁面偷頁后的一種補償方法。如果發(fā)生不可移動頁面偷頁后,我們將該頁面記錄到一個列表,等后續(xù)不可移動頁面類型存在空閑頁面時,將所偷的頁面遷移回不可移動頁面中,從而降低不可移動頁面的污染。

(2)降低分配頁幀號的隨機性

假設(shè)有一塊小內(nèi)存域如下,以下兩種內(nèi)存分配方式哪種會導致嚴重的內(nèi)存碎片化?

  • 頁面從頭部開始分配,直到尾部;
  • 頁面隨機從任何位置分配。
Linux 物理內(nèi)存外碎片化淺析

 

明顯是第二種內(nèi)存分配方式的對內(nèi)存外碎片化更不友好,而這點也是伙伴系統(tǒng)目前沒有解決的問題。伙伴系統(tǒng)雖然將內(nèi)存規(guī)劃成各種大小的內(nèi)存塊,以讓小內(nèi)存分配在小塊鏈表分配,盡量不污染大塊內(nèi)存鏈表,但是卻沒辦法保證小塊內(nèi)存具體是在物理內(nèi)存的哪個頁幀范圍分配。隨著系統(tǒng)的運行越久,小塊內(nèi)存的分配的物理頁幀號越發(fā)隨機,那么其導致碎片化的概率就會越高。

  • 預留法

根據(jù)這種情況,可以通過預留的方式進行相應(yīng)的優(yōu)化。

預留一定的內(nèi)存專門用于小塊內(nèi)存分配,經(jīng)過這個優(yōu)化措施后,可以有效降低小塊內(nèi)存分配的物理頁幀號的隨機性,從而降低小塊內(nèi)存污染內(nèi)存環(huán)境的概率。

預留一定的內(nèi)存專門用于大塊內(nèi)存分配,經(jīng)過該優(yōu)化措施后,預留的內(nèi)存被小塊內(nèi)存污染的概率就會降低,可以提升預留內(nèi)存分配大塊內(nèi)存的成功率。

另外關(guān)于降低伙伴系統(tǒng)分配頁幀號隨機性,還是存在很多優(yōu)化的措施,后續(xù)根據(jù)需要會專門開展一篇闡述該部分優(yōu)化的文章,如果讀者有興趣,到時可以查閱。

參考文獻

1、內(nèi)核源代碼

2、http://tinylab.org/lwn-368869/

3、https://patchwork.kernel.org/patch/

分享到:
標簽:物理 內(nèi)存 Linux
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定