來源:長(zhǎng)沙北大青鳥大計(jì)教育|發(fā)布時(shí)間:2020-07-19 16:08:08
摘要:湖南長(zhǎng)沙北大青鳥長(zhǎng)沙大計(jì)教育,成立于2006年,湖南長(zhǎng)沙IT學(xué)校排名領(lǐng)先品牌,學(xué)校依托了北京大學(xué)雄厚的技術(shù)資源,專注于職業(yè)教育,也是我國(guó)中南地區(qū)Java軟件工程師的人才搖籃。 北大青鳥長(zhǎng)沙校區(qū)選長(zhǎng)沙大計(jì)教育,選學(xué)一門,學(xué)通學(xué)透,求學(xué)電話:4008-0731-86
【為什么 Linux 需要虛擬內(nèi)存】
正文:操作系統(tǒng)中的CPU和主內(nèi)存(Mainmemory)都是稀缺資源,所有運(yùn)行在當(dāng)前操作系統(tǒng)的進(jìn)程會(huì)共享系統(tǒng)中的CPU和內(nèi)存資源,操作系統(tǒng)會(huì)使用CPU調(diào)度器分配CPU時(shí)間并引入虛擬內(nèi)存系統(tǒng)以管理物理內(nèi)存,本文會(huì)分析操作系統(tǒng)為什么需要虛擬內(nèi)存。在回答虛擬內(nèi)存存在的必要性之前,我們需要理解操作系統(tǒng)中的虛擬內(nèi)存是什么,它在操作系統(tǒng)中起到什么樣的作用。正如軟件工程中的其他抽象,虛擬內(nèi)存是操作系統(tǒng)物理內(nèi)存和進(jìn)程之間的中間層,它為進(jìn)程隱藏了物理內(nèi)存這一概念,為進(jìn)程提供了更加簡(jiǎn)潔和易用的接口以及更加復(fù)雜的功能。圖1–進(jìn)程和操作系統(tǒng)的中間層如果需要我們從頭設(shè)計(jì)一個(gè)操作系統(tǒng),讓系統(tǒng)中的進(jìn)程直接訪問主內(nèi)存中的物理地址應(yīng)該是非常自然的決定,早期的操作系統(tǒng)確實(shí)也都是這么實(shí)現(xiàn)的,進(jìn)程會(huì)使用目標(biāo)內(nèi)存的物理地址(PhysicalAddress)直接訪問內(nèi)存中的內(nèi)容,然而現(xiàn)代的操作系統(tǒng)都引入了虛擬內(nèi)存,進(jìn)程持有的虛擬地址(VirtualAddress)會(huì)經(jīng)過內(nèi)存管理單元(MemoryMangamentUnit)的轉(zhuǎn)換變成物理地址,然后再通過物理地址訪問內(nèi)存:圖2–虛擬內(nèi)存系統(tǒng)主存儲(chǔ)是相對(duì)比較稀缺的資源,雖然順序讀取只比磁盤快1個(gè)數(shù)量級(jí),但是它能提供極快的隨機(jī)訪問速度,從內(nèi)存上隨機(jī)讀取數(shù)據(jù)是磁盤的100,000倍,充分利用內(nèi)存的隨機(jī)訪問速度是改善程序執(zhí)行效率的有效方式。操作系統(tǒng)以頁為單位管理內(nèi)存,當(dāng)進(jìn)程發(fā)現(xiàn)需要訪問的數(shù)據(jù)不在內(nèi)存時(shí),操作系統(tǒng)可能會(huì)將數(shù)據(jù)以頁的方式加載到內(nèi)存中,這個(gè)過程是由上圖中的內(nèi)存管理單元(MMU)完成的。操作系統(tǒng)的虛擬內(nèi)存作為一個(gè)抽象層,起到了以下三個(gè)非常關(guān)鍵的作用:虛擬內(nèi)存可以利用磁盤起到緩存的作用,提高進(jìn)程訪問磁盤的速度;虛擬內(nèi)存可以為進(jìn)程提供獨(dú)立的內(nèi)存空間,簡(jiǎn)化程序的鏈接、加載過程并通過動(dòng)態(tài)庫共享內(nèi)存;虛擬內(nèi)存可以控制進(jìn)程對(duì)物理內(nèi)存的訪問,隔離不同進(jìn)程的訪問權(quán)限,提高系統(tǒng)的安全性;緩存我們可以將虛擬內(nèi)存看作是在磁盤上一片空間,當(dāng)這片空間中的一部分訪問比較頻繁時(shí),該部分?jǐn)?shù)據(jù)會(huì)以頁為單位被緩存到主存中以加速CPU訪問數(shù)據(jù)的性能,虛擬內(nèi)存利用空間較大的磁盤存儲(chǔ)作為『內(nèi)存』并使用主存儲(chǔ)緩存進(jìn)行加速,讓上層認(rèn)為操作系統(tǒng)的內(nèi)存很大而且很快,然而區(qū)域很大的磁盤并不快,而很快的內(nèi)存也并不大。圖3–虛擬內(nèi)存、主存和磁盤虛擬內(nèi)存中的虛擬頁(VirtualPage,PP)可能處于以下的三種狀態(tài)—未分配(Unallocated)、未緩存(Uncached)和已緩存(Cached),其中未分配的內(nèi)存頁是沒有被進(jìn)程申請(qǐng)使用的,也就是空閑的虛擬內(nèi)存,不占用虛擬內(nèi)存磁盤的任何空間,未緩存和已緩存的內(nèi)存頁分別表示僅加載到磁盤中的內(nèi)存頁和已經(jīng)加載到主存中的內(nèi)存頁。如上圖所示,圖中綠色的虛擬內(nèi)存頁由主存中的物理內(nèi)存頁(PhysicalPage,PP)支撐,所以它是已經(jīng)緩存過的,而黃色的虛擬內(nèi)存頁僅在磁盤中,所以沒有被物理內(nèi)存緩存。當(dāng)用戶程序訪問未被緩存的虛擬頁時(shí),硬件就會(huì)觸發(fā)缺頁中斷(PageFault,PF),在部分情況下,被訪問的頁面已經(jīng)加載到了物理內(nèi)存中,但是用戶程序的頁表(PageTable)并不存在該對(duì)應(yīng)關(guān)系,這時(shí)我們只需要在頁表中建立虛擬內(nèi)存到物理內(nèi)存的關(guān)系;在其他情況下,操作系統(tǒng)需要將磁盤上未被緩存的虛擬頁加載到物理內(nèi)存中。圖4–虛擬內(nèi)存的缺頁中斷因?yàn)橹鲀?nèi)存的空間是有限的,當(dāng)主內(nèi)存中不包含可以使用的空間時(shí),操作系統(tǒng)會(huì)從選擇合適的物理內(nèi)存頁驅(qū)逐回磁盤,為新的內(nèi)存頁讓出位置,選擇待驅(qū)逐頁的過程在操作系統(tǒng)中叫做頁面替換(PageReplacement)。缺頁中斷和頁面替換技術(shù)都是操作系統(tǒng)調(diào)頁算法(Paging)的一部分,該算法的目的就是充分利用內(nèi)存資源作為磁盤的緩存以提高程序的運(yùn)行效率。內(nèi)存管理虛擬內(nèi)存可以為正在運(yùn)行的進(jìn)程提供獨(dú)立的內(nèi)存空間,制造一種每個(gè)進(jìn)程的內(nèi)存都是獨(dú)立的假象,在64位的操作系統(tǒng)上,每個(gè)進(jìn)程都會(huì)擁有256TiB的內(nèi)存空間,內(nèi)核空間和用戶空間分別占128TiB,部分操作系統(tǒng)使用57位虛擬地址以提供128PiB的尋址空間。因?yàn)槊總(gè)進(jìn)程的虛擬內(nèi)存空間是完全獨(dú)立的,所以它們都可以完整的使用0×0000000000000000到0x00007FFFFFFFFFFF的全部?jī)?nèi)存。圖5–操作系統(tǒng)的虛擬內(nèi)存空間虛擬內(nèi)存空間只是操作系統(tǒng)中的邏輯結(jié)構(gòu),就像我們上面說的,應(yīng)用程序最終還是需要訪問物理內(nèi)存或者磁盤上的內(nèi)容。因?yàn)椴僮飨到y(tǒng)加了一個(gè)虛擬內(nèi)存的中間層,所以我們也需要為進(jìn)程實(shí)現(xiàn)地址翻譯器,實(shí)現(xiàn)從虛擬地址到物理地址的轉(zhuǎn)換,頁表是虛擬內(nèi)存系統(tǒng)中的重要數(shù)據(jù)結(jié)構(gòu),每一個(gè)進(jìn)程的頁表中都存儲(chǔ)了從虛擬內(nèi)存到物理內(nèi)存頁的映射關(guān)系,為了存儲(chǔ)64位操作系統(tǒng)中128TiB虛擬內(nèi)存的映射數(shù)據(jù),Linux在2.6.10中引入了四層的頁表輔助虛擬地址的轉(zhuǎn)換,在4.11中引入了五層的頁表結(jié)構(gòu),在未來還可能會(huì)引入更多層的頁表結(jié)構(gòu)以支持64位的虛擬地址。圖6–四層頁表結(jié)構(gòu)在如上圖所示的四層頁表結(jié)構(gòu)中,操作系統(tǒng)會(huì)使用最低的12位作為頁面的偏移量,剩下的36位會(huì)分四組分別表示當(dāng)前層級(jí)在上一層中的索引,所有的虛擬地址都可以用上述的多層頁表查找到對(duì)應(yīng)的物理地址。因?yàn)橛卸鄬拥捻摫斫Y(jié)構(gòu)可以用來轉(zhuǎn)換虛擬地址,所以多個(gè)進(jìn)程可以通過虛擬內(nèi)存共享物理內(nèi)存。我們?cè)?為什么Redis快照使用子進(jìn)程 一文中介紹的寫時(shí)復(fù)制就利用了虛擬內(nèi)存的這個(gè)特性,當(dāng)我們?cè)贚inux中調(diào)用 fork 創(chuàng)建子進(jìn)程時(shí),實(shí)際上只復(fù)制了父進(jìn)程的頁表。如下圖所示,父子進(jìn)程會(huì)通過不同的頁表指向相同的物理內(nèi)存:圖7–進(jìn)程間共享內(nèi)存虛擬內(nèi)存不僅可以在 fork 時(shí)用于共享進(jìn)程的物理內(nèi)存,提供寫時(shí)復(fù)制的機(jī)制,還能共享一些常見的動(dòng)態(tài)庫減少物理內(nèi)存的占用,所有的進(jìn)程都可能調(diào)用相同的操作系統(tǒng)內(nèi)核代碼,而C語言程序也會(huì)調(diào)用相同的標(biāo)準(zhǔn)庫。除了能夠共享內(nèi)存之外,獨(dú)立的虛擬內(nèi)存空間也會(huì)簡(jiǎn)化內(nèi)存的分配過程,當(dāng)用戶程序向操作系統(tǒng)申請(qǐng)堆內(nèi)存時(shí),操作系統(tǒng)可以分配幾個(gè)連續(xù)的虛擬頁,但是這些虛擬頁可以對(duì)應(yīng)到物理內(nèi)存中不連續(xù)的頁中。內(nèi)存保護(hù)操作系統(tǒng)中的用戶程序不應(yīng)該修改只讀的代碼段,也不應(yīng)該讀取或者修改內(nèi)核中的代碼和數(shù)據(jù)結(jié)構(gòu)或者訪問私有的以及其他的進(jìn)程的內(nèi)存,如果無法對(duì)用戶進(jìn)程的內(nèi)存訪問進(jìn)行限制,攻擊者就可以訪問和修改其他進(jìn)程的內(nèi)存影響系統(tǒng)的安全。如果每一個(gè)進(jìn)程都持有獨(dú)立的虛擬內(nèi)存空間,那么虛擬內(nèi)存中頁表可以理解成進(jìn)程和物理頁的『連接表』,其中可以存儲(chǔ)進(jìn)程和物理頁之間的訪問關(guān)系,包括讀權(quán)限、寫權(quán)限和執(zhí)行權(quán)限:圖8–讀權(quán)限、寫權(quán)限和執(zhí)行權(quán)限內(nèi)存管理單元可以決定當(dāng)前進(jìn)程是否有權(quán)限訪問目標(biāo)的物理內(nèi)存,這樣我們就最終將權(quán)限管理的功能全部收斂到虛擬內(nèi)存系統(tǒng)中,減少了可能出現(xiàn)風(fēng)險(xiǎn)的代碼路徑?偨Y(jié)虛擬內(nèi)存的設(shè)計(jì)方法可以說是軟件工程中的常見手段,通過結(jié)合磁盤和內(nèi)存各自的優(yōu)勢(shì),利用中間層對(duì)資源進(jìn)行更合理地調(diào)度充分提高資源的利用率并提供和諧以及統(tǒng)一的抽象,而在實(shí)際的業(yè)務(wù)場(chǎng)景中,類似的緩存邏輯也比較常見。操作系統(tǒng)的虛擬內(nèi)存是非常復(fù)雜的組件,沒有工程師能夠了解其中的全部細(xì)節(jié),不過了解虛擬內(nèi)存的整體設(shè)計(jì)也很有價(jià)值,我們能夠從中找到很多軟件設(shè)計(jì)的方法。我們重新回到今天的問題—Linux操作系統(tǒng)中為什么需要虛擬內(nèi)存:虛擬內(nèi)存可以結(jié)合磁盤和物理內(nèi)存的優(yōu)勢(shì)為進(jìn)程提供看起來速度足夠快并且容量足夠大的存儲(chǔ);虛擬內(nèi)存可以為進(jìn)程提供獨(dú)立的內(nèi)存空間并引入多層的頁表結(jié)構(gòu)將虛擬內(nèi)存翻譯成物理內(nèi)存,進(jìn)程之間可以共享物理內(nèi)存減少開銷,也能簡(jiǎn)化程序的鏈接、裝載以及內(nèi)存分配過程;虛擬內(nèi)存可以控制進(jìn)程對(duì)物理內(nèi)存的訪問,隔離不同進(jìn)程的訪問權(quán)限,提高系統(tǒng)的安全性;到最后,我們還是來看一些比較開放的相關(guān)問題,有興趣的讀者可以仔細(xì)思考一下下面的問題:為什么每層的頁表結(jié)構(gòu)只能夠負(fù)責(zé)9位虛擬地址的尋址?64位的虛擬內(nèi)存在操作系統(tǒng)中需要多少層的頁表結(jié)構(gòu)才能尋址?
拓展閱讀:
北大青鳥哪個(gè)校區(qū)最好
與長(zhǎng)沙商學(xué)院最近的北大青鳥學(xué)校
長(zhǎng)沙北大青鳥學(xué)?煽繂
長(zhǎng)沙北大青鳥學(xué)校
長(zhǎng)沙北大青鳥學(xué)費(fèi)一覽表
全程面授,不高薪都難
申請(qǐng)成功后,我們將在24小時(shí)內(nèi)與您聯(lián)系
招生熱線: 4008-0731-86 / 0731-82186801
學(xué)校地址: 長(zhǎng)沙市天心區(qū)團(tuán)結(jié)路6號(hào)
Copyright © 2006 | 湖南大計(jì)信息科技有限公司 版權(quán)所有
湘ICP備14017520號(hào)-3