linux之進(jìn)程地址空間和物理內(nèi)存管理

所謂進(jìn)程地址空間(process address space)囚戚,就是從進(jìn)程的視角看到的地址空間阿趁,是進(jìn)程運(yùn)行時所用到的虛擬地址的集合螺捐。

32位系統(tǒng)的進(jìn)程地址空間

以IA-32處理器為例请梢,其虛擬地址為32位忧额,因此其虛擬地址空間的范圍為4gb泌神,Linux系統(tǒng)將地址空間按3:1比例劃分良漱,其中用戶空間(user space)占3GB,內(nèi)核空間(kernel space)占1GB欢际。

假設(shè)物理內(nèi)存也是4GB(事實(shí)上母市,虛擬地址空間的范圍不一定需要和物理地址空間的大小相同),則虛擬地址空間和物理地址空間的轉(zhuǎn)換如下圖所示:


image.png

因?yàn)閮?nèi)核的虛擬地址空間只有1GB损趋,但它需要訪問整個4GB的物理空間患久,因此從物理地址0~896MB的部分(ZONE_DMA+ZONE_NORMAL),直接加上3GB的偏移(在Linux中用PAGE_OFFSET表示)浑槽,就得到了對應(yīng)的虛擬地址蒋失,這種映射方式被稱為線性/直接映射(Direct Map)。

而896M4GB的物理地址部分(ZONE_HIGHMEM)需要映射到(3G+896M)4GB這128MB的虛擬地址空間桐玻,顯然也按線性映射是不行的篙挽。

采用的是做法是,ZONE_HIGHMEM中的某段物理內(nèi)存和這128M中的某段虛擬空間建立映射镊靴,完成所需操作后铣卡,需要斷開與這部分虛擬空間的映射關(guān)系链韭,以便ZONE_HIGHMEM中其他的物理內(nèi)存可以繼續(xù)往這個區(qū)域映射,即動態(tài)映射的方式煮落。

用戶空間的進(jìn)程只能訪問整個虛擬地址空間的03GB部分敞峭,不能直接訪問3G4GB的內(nèi)核空間部分,但出于對性能方面的考慮州邢,Linux中內(nèi)核使用的地址也是映射到進(jìn)程地址空間的(被所有進(jìn)程共享)儡陨,因此進(jìn)程的虛擬地址空間可視為整個4GB(雖然實(shí)際只有3GB)。

image.png

NUMA

所謂物理內(nèi)存量淌,就是安裝在機(jī)器上的骗村,實(shí)打?qū)嵉膬?nèi)存設(shè)備(不包括硬件cache),被CPU通過總線訪問呀枢。在多核系統(tǒng)中胚股,如果物理內(nèi)存對所有CPU來說沒有區(qū)別,每個CPU訪問內(nèi)存的方式也一樣裙秋,則這種體系結(jié)構(gòu)被稱為Uniform Memory Access(UMA)琅拌。

如果物理內(nèi)存是分布式的,由多個cell組成(比如每個核有自己的本地內(nèi)存)摘刑,那么CPU在訪問靠近它的本地內(nèi)存的時候就比較快进宝,訪問其他CPU的內(nèi)存或者全局內(nèi)存的時候就比較慢,這種體系結(jié)構(gòu)被稱為Non-Uniform Memory Access(NUMA)枷恕。

以上是硬件層面上的NUMA党晋,而作為軟件層面的Linux,則對NUMA的概念進(jìn)行了抽象徐块。即便硬件上是一整塊連續(xù)內(nèi)存的UMA未玻,Linux也可將其劃分為若干的node。同樣胡控,即便硬件上是物理內(nèi)存不連續(xù)的NUMA扳剿,Linux也可將其視作UMA。

所以昼激,在Linux系統(tǒng)中庇绽,你可以基于一個UMA的平臺測試NUMA上的應(yīng)用特性。從另一個角度橙困,UMA就是只有一個node的特殊NUMA敛劝,所以兩者可以統(tǒng)一用NUMA模型表示。

image.png

在NUMA系統(tǒng)中纷宇,當(dāng)Linux內(nèi)核收到內(nèi)存分配的請求時夸盟,它會優(yōu)先從發(fā)出請求的CPU本地或鄰近的內(nèi)存node中尋找空閑內(nèi)存,這種方式被稱作local allocation像捶,local allocation能讓接下來的內(nèi)存訪問相對底層的物理資源是local的上陕。

每個node由一個或多個zone組成(我們可能經(jīng)常在各種對虛擬內(nèi)存和物理內(nèi)存的描述中迷失桩砰,但以后你見到zone,就知道指的是物理內(nèi)存)释簿,每個zone又由若干page frames組成(一般page frame都是指物理頁面)亚隅。

image.png

Page Frame

雖然內(nèi)存訪問的最小單位是byte或者word,但MMU是以page為單位來查找頁表的庶溶,page也就成了Linux中內(nèi)存管理的重要單位煮纵。包括換出(swap out)、回收(relcaim)偏螺、映射等操作行疏,都是以page為粒度的。

因此套像,描述page frame的struct page自然成為了內(nèi)核中一個使用頻率極高酿联,非常重要的結(jié)構(gòu)體,來看下它是怎樣構(gòu)成的(為了講解需要并非最新內(nèi)核代碼):

struct page {
    unsigned long flags;
    atomic_t count;  
    atomic_t _mapcount; 
    struct list_head lru;
    struct address_space *mapping;
    unsigned long index;         
    ...  
} 
  • flags表示page frame的狀態(tài)或者屬性夺巩,包括和內(nèi)存回收相關(guān)的PG_active, PG_dirty, PG_writeback, PG_reserved, PG_locked, PG_highmem等贞让。其實(shí)flags是身兼多職的,它還有其他用途柳譬,這將在下文中介紹到喳张。
  • count表示引用計數(shù)。當(dāng)count值為0時美澳,該page frame可被free掉销部;如果不為0,說明該page正在被某個進(jìn)程或者內(nèi)核使用人柿,調(diào)用page_count()可獲得count值。
  • _mapcount表示該page frame被映射的個數(shù)忙厌,也就是多少個page table entry中含有這個page frame的PFN凫岖。
  • lru是"least recently used"的縮寫,根據(jù)page frame的活躍程度(使用頻率)逢净,一個可回收的page frame要么掛在active_list雙向鏈表上哥放,要么掛在inactive_list雙向鏈表上,以作為頁面回收的選擇依據(jù)爹土,lru中包含的就是指向所在鏈表中前后節(jié)點(diǎn)的指針(參考這篇文章)甥雕。
  • 如果一個page是屬于某個文件的(也就是在page cache中),則mapping指向文件inode對應(yīng)的address_space(這個結(jié)構(gòu)體雖然叫address_space胀茵,但并不是進(jìn)程地址空間里的那個address space)社露,index表示該page在文件內(nèi)的offset(以page size為單位)。

有了文件的inode和index琼娘,當(dāng)這個page的內(nèi)容需要和外部disk/flash上對應(yīng)的部分同步時峭弟,才可以找到具體的文件位置附鸽。如果一個page是anonymous的,則mapping指向表示swap cache的swapper_space瞒瘸,此時index就是swapper_space內(nèi)的offset坷备。

需要注意的是,struct page描述和管理的是這4KB的物理內(nèi)存情臭,它并不關(guān)注這段內(nèi)存中的數(shù)據(jù)變化省撑。

Zone

因?yàn)橛布南拗疲瑑?nèi)核不能對所有的page frames采用同樣的處理方法俯在,因此它將屬性相同的page frames歸到一個zone中竟秫。對zone的劃分與硬件相關(guān),對不同的處理器架構(gòu)是可能不一樣的朝巫。

比如在i386中鸿摇,一些使用DMA的設(shè)備只能訪問016MB的物理空間,因此將016MB劃分為了ZONE_DMA劈猿。ZONE_HIGHMEM則是適用于要訪問的物理地址空間大于虛擬地址空間拙吉,不能建立直接映射的場景。除開這兩個特殊的zone揪荣,物理內(nèi)存中剩余的部分就是ZONE_NORMAL了筷黔。

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仗颈,隨后出現(xiàn)的幾起案子佛舱,更是在濱河造成了極大的恐慌,老刑警劉巖挨决,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件请祖,死亡現(xiàn)場離奇詭異,居然都是意外死亡脖祈,警方通過查閱死者的電腦和手機(jī)肆捕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盖高,“玉大人慎陵,你說我怎么就攤上這事∮靼拢” “怎么了席纽?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撞蚕。 經(jīng)常有香客問我润梯,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任仆救,我火速辦了婚禮抒和,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘彤蔽。我一直安慰自己摧莽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布顿痪。 她就那樣靜靜地躺著镊辕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚁袭。 梳的紋絲不亂的頭發(fā)上征懈,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機(jī)與錄音揩悄,去河邊找鬼卖哎。 笑死,一個胖子當(dāng)著我的面吹牛删性,可吹牛的內(nèi)容都是我干的亏娜。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼蹬挺,長吁一口氣:“原來是場噩夢啊……” “哼维贺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巴帮,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤溯泣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后榕茧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垃沦,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年用押,在試婚紗的時候發(fā)現(xiàn)自己被綠了肢簿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡只恨,死狀恐怖译仗,靈堂內(nèi)的尸體忽然破棺而出抬虽,到底是詐尸還是另有隱情官觅,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布阐污,位于F島的核電站休涤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜功氨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一序苏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捷凄,春花似錦忱详、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桶错,卻和暖如春航唆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背院刁。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工糯钙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人退腥。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓任岸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阅虫。 傳聞我的和親對象是個殘疾皇子演闭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344