CSAPP——第九章 虛擬內(nèi)存

幾個(gè)概念

  1. 程序
    存儲(chǔ)在磁盤上的文件手蝎,在執(zhí)行的時(shí)候加載如內(nèi)存
  2. 內(nèi)存
    分為DRAM,和SRAM
    DRAM:可以就看成我們買的內(nèi)存條
    SRAM:可以就看是CPU中的一二三級(jí)緩存

虛擬內(nèi)存

好處:

  1. 將主存(DRAM)進(jìn)行抽象,通過(guò)分頁(yè)機(jī)制,實(shí)現(xiàn):主存中保存活動(dòng)的區(qū)域哥纫,并根據(jù)需要(缺頁(yè)異常和正常存取)在主存之間傳送數(shù)據(jù)酌予。高效的使用了主存
  2. 為進(jìn)城提供一直的地址空間磺箕,簡(jiǎn)化內(nèi)存管理,和程序的鏈接
  3. 保護(hù)每個(gè)進(jìn)城的地址空間不被其他進(jìn)程破壞抛虫。

程序和DRAM

DRAM可以看做是一個(gè)M個(gè)連續(xù)字節(jié)大小的數(shù)組松靡,每個(gè)字節(jié)都有唯一的地址:物理地址。
CPU直接訪問(wèn)DRAM使用物理地址的方式成為:物理尋址建椰。
早起程序使用物理尋址雕欺,但是目前大多使用虛擬尋址。目前仍有一些特殊的機(jī)器使用物理尋址棉姐。

虛擬尋址

指的是:CPU訪問(wèn)DRAM的地址不是物理地址屠列,稱為虛擬地址。需要由CPU中的內(nèi)存管理單元(MMU)將虛擬地址轉(zhuǎn)換為物理地址伞矩。然后MMU利用轉(zhuǎn)換得到的物理地址發(fā)給DRAM笛洛,DRAM將數(shù)據(jù)直接送給CPU。

虛擬尋址主存

虛擬內(nèi)存VM

在物理內(nèi)存上面抽象出的一層成為虛擬內(nèi)存乃坤,主要是用來(lái)管理物理內(nèi)存的苛让。
虛擬內(nèi)存對(duì)應(yīng)一個(gè)虛擬地址空間沟蔑,物理內(nèi)存對(duì)應(yīng)一個(gè)物理地址空間。也就是兩個(gè)M字節(jié)的連續(xù)數(shù)組狱杰。分別兩種尋址方式瘦材。
其中虛擬內(nèi)存中的某個(gè)地址對(duì)應(yīng)物理內(nèi)存中的某個(gè)地址,可以使一對(duì)多的關(guān)系仿畸。

虛擬頁(yè)

VM將內(nèi)存又劃分為很多的小塊食棕,每塊大4K,不固定错沽,可變簿晓,以后用P表示一個(gè)頁(yè)的大小,每個(gè)單位成為虛擬頁(yè)
同時(shí)物理內(nèi)存頁(yè)被分頁(yè)千埃,每個(gè)單位成為頁(yè)幀
虛擬內(nèi)存通過(guò)分頁(yè)機(jī)制達(dá)到將將程序的活動(dòng)部分加載進(jìn)內(nèi)存抢蚀。

可以理解為,將程序也按照每塊P大小分割镰禾,并不全部將程序加載進(jìn)內(nèi)存皿曲,而是在需要那一頁(yè)的時(shí)候,將這一頁(yè)加載進(jìn)內(nèi)存吴侦。(這里涉及到缺頁(yè)異常)

每個(gè)頁(yè)可能有如下三種不想交的狀態(tài)屋休,每個(gè)時(shí)刻只能有一種:

  1. 未分配
    指的是,VM中的一頁(yè)备韧,并沒(méi)有被使用劫樟。所以這一虛擬頁(yè)沒(méi)有對(duì)應(yīng)的頁(yè)幀(物理內(nèi)存的一頁(yè))。
  2. 未緩存
    指的是织堂,虛擬頁(yè)被內(nèi)存使用叠艳,相當(dāng)于一個(gè)變量被聲明。但是還沒(méi)有定義易阳。所以附较,只是在VM中占用,但是還沒(méi)有分配頁(yè)幀潦俺。(沒(méi)有分配頁(yè)幀的意思是拒课,對(duì)應(yīng)的值沒(méi)有加載進(jìn)物理內(nèi)存)
  3. 以緩存
    值得是,VM中的虛擬頁(yè)事示,已經(jīng)連接到頁(yè)幀早像,同時(shí)也從磁盤中讀取數(shù)據(jù)存儲(chǔ)在對(duì)應(yīng)的頁(yè)幀。
內(nèi)存做緩存

圖上說(shuō)是虛擬頁(yè)存儲(chǔ)在磁盤上肖爵?大哥卢鹦,主存是緩存,虛擬頁(yè)怎么可能比緩存慢劝堪。

頁(yè)表?xiàng)l目(Page Table Entry)維護(hù)了虛擬頁(yè)到頁(yè)幀的轉(zhuǎn)換冀自,由操作系統(tǒng)維護(hù)谁榜。
頁(yè)表?xiàng)l目存儲(chǔ)在物理內(nèi)存中。
頁(yè)表?xiàng)l目每一項(xiàng)由:有效位凡纳,和物理頁(yè)號(hào)組成。
有效位指的是:1該虛擬頁(yè)已經(jīng)指向頁(yè)幀(以緩存)帝蒿,0該虛擬頁(yè)沒(méi)有被使用或者已使用但是未指向頁(yè)幀(未分配和未緩存)荐糜。
物理頁(yè)號(hào),指的是虛擬頁(yè)指向的頁(yè)幀地址葛超。

虛擬頁(yè)->頁(yè)幀

指向物理內(nèi)存的是以緩存暴氏,指向VP的是未緩存,NULL的代表未分配绣张。

除了有效位以外答渔,頁(yè)表中還可以存儲(chǔ)其他的信息,比如是否可讀之類的侥涵。

頁(yè)命中

命中可以理解成沼撕,當(dāng)CPU取數(shù)據(jù)的時(shí)候芜飘,能夠直接主存中獲取,成為命中嗦明。如果數(shù)據(jù)還沒(méi)有存進(jìn)主存成為未命中。
在虛擬內(nèi)存中娶牌,DRAM緩存不命中成為缺頁(yè)。

當(dāng)CPU讀取數(shù)據(jù)的時(shí)候回發(fā)生兩種情況:

1. 虛擬地址指向的表項(xiàng)PTE中有效位為0

可能是未緩存或者是未分配汹桦,這時(shí)候觸發(fā)一個(gè)缺頁(yè)異常!
linux下营勤,MMU試圖翻譯一個(gè)虛擬地址A時(shí),觸發(fā)一個(gè)缺頁(yè)葛作。這個(gè)異常導(dǎo)致控制轉(zhuǎn)移到內(nèi)核的缺頁(yè)處理程序::

  1. 確認(rèn)A地址是合法。
    缺頁(yè)處理程序搜索區(qū)域結(jié)構(gòu)的鏈表猖凛,把A和每個(gè)區(qū)域結(jié)構(gòu)中的vm_startvm_end做比較赂蠢。如果指令不合法,發(fā)生一個(gè)段錯(cuò)誤segmatation fault,結(jié)束程序辨泳。
    因?yàn)锳地址可能是個(gè)函數(shù)虱岂,或是堆上或是棧上數(shù)據(jù)玖院,所有要每個(gè)都搜索。
  2. 地址合法的情況下第岖,確認(rèn)是否有權(quán)限
    也就是难菌,進(jìn)城是否又讀寫或執(zhí)行該區(qū)域內(nèi)頁(yè)幀的權(quán)限。
  3. 權(quán)限合法的情況下蔑滓,加載進(jìn)主存
    當(dāng)物理內(nèi)存未滿的情況下郊酒,可能是直接找個(gè)空閑的地方加載頁(yè)幀。(不知道啊键袱。書上都沒(méi)寫燎窘。可能是這樣)
    否則蹄咖,缺頁(yè)處理程序在物理內(nèi)存中選擇一個(gè)犧牲頁(yè)褐健,然后,如果該犧牲也被修改過(guò)了澜汤,那么將頁(yè)幀內(nèi)容寫會(huì)磁盤蚜迅。然后將新的磁盤內(nèi)容加載進(jìn)頁(yè)幀。同時(shí)更新頁(yè)表俊抵。
    當(dāng)缺頁(yè)處理程序返回的時(shí)候慢叨,CPU重新啟動(dòng)引起缺頁(yè)的指令,這時(shí)候A已經(jīng)是以緩存的务蝠。正常讀取拍谐。
    選擇犧牲頁(yè),應(yīng)該是又算法的馏段,局部性原理轩拨。

其中在第一部搜索接受的時(shí)候,結(jié)構(gòu)是這樣的:

每個(gè)線程都有的結(jié)構(gòu)

缺頁(yè)之前:

image.png

缺頁(yè)處理程序返回之后:

image.png

當(dāng)我工作集超出了物理內(nèi)存的大小院喜,會(huì)產(chǎn)生抖動(dòng)亡蓉,頁(yè)面將不斷的換進(jìn)換出。

虛擬頁(yè)與共享庫(kù)

當(dāng)多個(gè)程序調(diào)用同一個(gè)共享庫(kù)時(shí)喷舀,程序沒(méi)必要為每一個(gè)程序加載一次共享庫(kù)硫麻。
而是不同程序的虛擬頁(yè)指向同一頁(yè)幀拿愧。
產(chǎn)生了多對(duì)一的情形:
不同程序的虛擬頁(yè)對(duì)應(yīng)同一頁(yè)幀

共享頁(yè)面

頁(yè)面調(diào)度和虛擬地址空間的結(jié)合有點(diǎn):

  1. 簡(jiǎn)化程序鏈接
    每個(gè)程序可以采用相同基本格式,從同一虛擬地址開(kāi)始唾戚。
  2. 簡(jiǎn)化加載
    當(dāng)程序加載進(jìn)內(nèi)存的時(shí)候叹坦,只需要分配虛擬頁(yè)募书,而不必加載進(jìn)頁(yè)幀。當(dāng)需要的時(shí)候毕箍,發(fā)生缺頁(yè)異常而柑,然后加載。按需加載粹排。
  3. 簡(jiǎn)化共享
    方便共享庫(kù)的加載顽耳。
  4. 簡(jiǎn)化內(nèi)存分配
    在虛擬地址空間中連續(xù)的地址妙同,在物理地址空間中不一定連續(xù)粥帚。
    也就是程序在堆棧中分配的地址芒涡,在物理空間中可能并不是連續(xù)的。

地址翻譯過(guò)程

  1. 處理器生成虛擬地址傳送給MMU
  2. MMU生成PTE地址赠群,并從主存或高速緩存請(qǐng)求乎串,去訪問(wèn)的是頁(yè)表?xiàng)l目叹誉。應(yīng)該是將整一項(xiàng)返回給MMU
  3. 高速緩存(查找頁(yè)表?xiàng)l目)以后返回一項(xiàng)給MMU

命中情況下

  1. MMU根據(jù)返回的PTE(此時(shí)PTE的有效位為1)構(gòu)造物理地址长豁,再次發(fā)送給主存
  2. 主存直接讀取數(shù)據(jù)匠襟,發(fā)送給CPU
頁(yè)面命中

缺頁(yè)

  1. PTE有效位為0酸舍,MMU觸發(fā)缺頁(yè)異常。CPU中的控制轉(zhuǎn)移到內(nèi)核中的缺一處理程序
  2. 確定犧牲頁(yè)忽舟,替換叮阅。缺頁(yè)處理程序更新PTE
  3. 確立處理程序返回浩姥,CPU再次執(zhí)行導(dǎo)致缺頁(yè)的程序

TLB緩存

CPU每次請(qǐng)求状您,MMU都去查找一次過(guò)于浪費(fèi)膏孟。
因此MMU中有一個(gè)翻譯后背緩沖器(Tanslation Lookaside Buffer)
在上面的第2部時(shí)。變?yōu)椋篗MU去查找TLB颗搂,如果沒(méi)查找到幕垦,再去主存中查找頁(yè)表?xiàng)l目先改。返回后跟新TLB仇奶。

TLB

頁(yè)表分級(jí)

image.png

暫時(shí)不是很懂。不過(guò)有點(diǎn)理解吧

二. linux虛擬內(nèi)存系統(tǒng)

execve函數(shù)

調(diào)用execve函數(shù)以后執(zhí)行以下步驟

  1. 刪除已存在的用戶區(qū)域
    刪除當(dāng)前進(jìn)程虛擬地址中用戶部分已存在的結(jié)構(gòu)别惦,.text掸掸,.data等
  2. 映射私有區(qū)域
    為因程序的代碼扰付,數(shù)據(jù)仁讨,bss和站區(qū)域創(chuàng)建新的結(jié)構(gòu)洞豁。
    這些區(qū)域都是私有的,代碼區(qū)和數(shù)據(jù)區(qū)映射對(duì)應(yīng)文件的.text闰挡,.data礁哄。而.bss映射到匿名文件桐绒,其大小保存在要執(zhí)行的文件中茉继。
  3. 映射共享區(qū)域
    如果要執(zhí)行的程序調(diào)用了共享庫(kù)之類的烁竭,那么需要將這些庫(kù)映射到用戶虛擬空間中的共享區(qū)域派撕。
  4. 設(shè)置程序計(jì)數(shù)器(PC)
    最后一件事情是設(shè)置進(jìn)程上下文中的程序計(jì)數(shù)器终吼,使其指向代碼區(qū)域的入口點(diǎn)。

加載器執(zhí)行程序

圖中請(qǐng)求二進(jìn)制0的地方,為映射到匿名文件mmap()

動(dòng)態(tài)內(nèi)存分配

分配器指的是new,delete,malloc,free這些良姆。
分為顯示分配器歇盼,如上面的四個(gè)豹缀,也就是需要用戶手動(dòng)釋放
隱式分配器也就是垃圾收集器慨代,比如java等語(yǔ)言。

malloc實(shí)現(xiàn)

#include <stdlib.h>
void *malloc(size_t size);

返回一個(gè)void *指針氮惯,可以隱式轉(zhuǎn)化為任意類型妇汗。
其分配的塊總是對(duì)其的说莫。32下為8的倍數(shù)储狭,64位下是16的倍數(shù)辽狈。
malloc并不初始化其分配的內(nèi)存,calloc初始化驮配。
malloc的實(shí)現(xiàn)壮锻,基于mmap()sbrk()躯保。

#include <unistd.h>
void *sbrk(intptr_t incr);

以后補(bǔ)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末途事,一起剝皮案震驚了整個(gè)濱河市尸变,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碱工,老刑警劉巖怕篷,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異麻削,居然都是意外死亡呛哟,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)借帘,“玉大人淌铐,你說(shuō)我怎么就攤上這事蔫缸∈奥担” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵弟跑,是天一觀的道長(zhǎng)孟辑。 經(jīng)常有香客問(wèn)我饲嗽,道長(zhǎng),這世上最難降的妖魔是什么吞加? 我笑而不...
    開(kāi)封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮巫财,結(jié)果婚禮上哩陕,老公的妹妹穿的比我還像新娘平项。我一直安慰自己,他們只是感情好悍及,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布闽瓢。 她就那樣靜靜地躺著,像睡著了一般心赶。 火紅的嫁衣襯著肌膚如雪扣讼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天缨叫,我揣著相機(jī)與錄音椭符,去河邊找鬼。 笑死耻姥,一個(gè)胖子當(dāng)著我的面吹牛销钝,可吹牛的內(nèi)容都是我干的婉商。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼滤祖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼汤求!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤航瞭,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡只冻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年舍悯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狗准,到底是詐尸還是另有隱情饼酿,我是刑警寧澤药版,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布还栓,位于F島的核電站辽聊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏隙轻。R本人自食惡果不足惜斑匪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一贮勃、第九天 我趴在偏房一處隱蔽的房頂上張望泉孩。 院中可真熱鬧,春花似錦句喷、人聲如沸肴裙。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春合溺,著一層夾襖步出監(jiān)牢的瞬間缀台,已是汗流浹背贸伐。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工捉邢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留藐翎,地道東北人赤惊。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蛹含,于是被迫代替她去往敵國(guó)和親酷窥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咽安,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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