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