你是否疑惑過為什么兩個進程可以擁有同一個地址,明明某個地址處的物理內存只有一塊啊。這其實是系統提供的一種對主存的一種抽象,叫做虛擬存儲器。它為每個進程提供了一個大的、一致的、和私有的地址空間。虛擬存儲器提供了三個重要的能力:1.將主存作為一個存儲在磁盤上的地址空間的緩存。2.為每個進程提供一致的地址空間。3.保護每個進程的地址空間不被其他進程破壞。
虛擬地址和物理地址
CPU生成一個虛擬地址來訪問主存,這個虛擬地址經過地址翻譯生成適當的物理地址。物理存儲器每個字節都被一個物理地址標識。
一次訪問某個虛擬地址的過程
如圖
第一種情況:假設要訪問某個虛擬地址,此處的有效位為1,并且指向物理存儲器VP2。那么我們要訪問的字節肯定就在VP2這個物理頁中。此次訪問時頁命中的。
第二種情況:假設第二次訪問,虛擬地址映射到了VP3,此時頁面不在物理存儲器,而在磁盤,并且物理頁面也已經滿了,那么我們要從物理頁中選擇一個頁面進行淘汰,將VP3調入物理內存(耗時操作)。缺頁處理后如下圖:
我們將VP3調入內存,將VP4調出磁盤,中斷后我們再訪問這個虛擬地址時,VP3已經在內存中了。
地址翻譯
地址翻譯將虛擬地址翻譯為物理地址。虛擬地址被劃分為虛擬頁號和虛擬頁內偏移,虛擬頁號用來定位頁表中的頁表項,頁表項中保存著物理頁號,也就得到了物理頁號。虛擬頁偏移和物理頁偏移相同。有了物理頁號和物理頁偏移,就得到了物理地址。
存儲器映射
存儲器映射提供了一種機制,可以使多個進程共享同一個對象。
如下圖所示。如果一個進程將一個共享對象映射到它的虛擬地址空間的一個區域內,那么這個進程對這個區域的任何寫操作,對于那些也把這個共享對象映射到它的虛擬地址空間的進程而言也是可見的。
如果某個對象是私有對象時,那么使用一種寫時拷貝技術,來推遲拷貝的時間。具體過程如下圖。
兩個進程同時將一個私有對象映射到自己的虛擬地址空間,只要沒有寫操作,那么這兩個進程共享內存中的同一個對象,節約了內存。當某個進程執行寫操作時,因為對象是私有的,如果直接修改將會反應到另一個進程中。所以要對原對象進行拷貝,然后修改拷貝后的對象。
總結
了解了虛擬存儲器,我們對進程,虛擬地址這些概念是不是理解更深刻了呢。
參考:《深入理解計算機系統》