天天看點

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體

當計算機需要運作一個程序時,需要将程序加載到記憶體中,并且給其配置設定相應的運作資源。記憶體中同一時間可以存在N個程序,這些程序共享有限的CPU資源和記憶體資源。思考一個問題,這N個程序的資料量肯定是遠遠超過了記憶體的大小的。比如一個3A遊戲,動辄幾十G,如果作業系統一次性将所有的資源都加載到記憶體中,先不說存不下,在效率方面也是我們無法接受的。那麼作業系統是如何用有限的記憶體資源去描述遠大于記憶體的計算機程式呢?這個就是我們需要了解的内容。

一、CPU尋址

CPU在運作時需要将資料從主存加載到寄存器或者其他電子器件中。CPU在主存上尋找這個資料的行為就叫做CPU尋址。CPU的尋址分為兩種,實體尋址和虛拟尋址。

1、實體尋址

從實體的角度上來看,記憶體的大小是固定的。作業系統将其組織成一個由M個連續的

大小的存儲單元組成的數組,字的大小就是作業系統的位大小,比如64位作業系統,一個字就是64bit,即8位元組。作業系統賦予每一個存儲單元一個唯一的标記,這個标記就是該存儲單元的

實體位址,

CPU以實體位址直接從主存中加載資料的方式也就是

實體尋址

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體
2、虛拟尋址

就像文章開頭提到的,如果對于一個很大的程式,其資料不可能一次性全部加載到記憶體中,而是每次隻能加載部分資源,其餘的仍然在磁盤上。對于磁盤上的資源,用到的時候才加載到記憶體中。

對于超出實體位址所能描述的那部分資料,作業系統也為其配置設定了一個邏輯上的位址,即

虛拟位址

。當cpu通過虛拟位址來從記憶體上加載資源時,首先要經過一次位址的轉換,即先将虛拟位址轉換成實體位址,然後再通過實體尋址的方式加載資料,這種方式叫做

虛拟尋址

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體

虛拟位址和實體位址的轉換需要CPU晶片上一個叫做MMU(記憶體管理單元)的硬體來提供支援。

3、位址空間

實體位址的範圍理論上的上限,就是記憶體的規格。比如對于一個8GB的記憶體,假設目前作業系統的位數為n,則理論上的實體位址範圍為 2 ^ 30 * 8 * 8 / n。但是,由于最多隻能由一個存儲單元來表示資料的位址,是以實際上能夠使用到的範圍最大為2 ^ n - 1,是以對于32位作業系統來說,其最大的實體位址範圍隻有4GB。就算你給32位作業系統裝一個8GB的記憶體,也會被浪費掉。但是如果記憶體隻有2GB,則其實際的實體位址範圍則隻有2 ^ 30 * 2 * 8 / n。

而對于虛拟位址的範圍,則跟作業系統的位數有關,與記憶體的實際規格無關。虛拟位址的最大範圍就是一個字所能表示的最大數值。是以對于32位作業系統,虛拟位址範圍就是2 ^ 32 - 1約等于4GB,而對于64位作業系統來說,其位址範圍有(2 ^ 64 - 1)B,足夠我們使用了。

二、虛拟記憶體和記憶體

從概念上講,虛拟記憶體就是由存放在磁盤上的N個連續的位元組大小的存儲單元組成的數組,每個存儲單元都有一個唯一的虛拟位址作為索引。由于記憶體中隻能加載部分磁盤上的資料,為了進行結構化的管理,虛拟記憶體系統使用

磁盤上較低層級的部分作為磁盤和主存之間的傳輸單元

磁盤分層存儲

),即

磁盤和記憶體之間的緩存

。虛拟記憶體系統将這部分緩存分割成一個個大小固定的資料塊,被稱為

虛拟頁(VP)

。同樣的,實體記憶體為了能夠和虛拟頁進行一一對應,也被分成了一個個的資料塊,被稱為

頁幀(PP)

,虛拟頁和頁幀的大小是相同的。

是以在任意時刻,虛拟頁面的集合都分為三個不相交的子集:

1、未建立的虛拟頁(

未配置設定

2、已建立但是未配置設定給頁幀的虛拟頁(

未緩存

3、已配置設定給頁幀的虛拟頁(

已緩存

這裡的緩存是相當于把記憶體當做CPU和磁盤之間的高速緩存(了解這句話很重要)
加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體

上圖是一個具有8個虛拟頁的虛拟記憶體系統。其中0和3尚未配置設定,即這兩個作為

磁盤-記憶體

緩存的低層級的磁盤上未存儲來自高層級磁盤上的資料。1、4、6三個虛拟頁表示這三個作為

磁盤-記憶體

緩存的低層級的磁盤上已經存儲了來自高層級磁盤上的資料,并且這些資料已經加載到記憶體中的頁幀中去了。剩下的2、5、7表示雖然資料已經存儲到

磁盤-記憶體

緩存,但是還尚未加載到記憶體的頁幀中去。

三、虛拟記憶體系統

如果單獨的看

記憶體和CPU

,那麼他們之間又存在着一個緩存系統,即L1、L2、L3緩存。不過記憶體和L1、L2、L3緩存之間的速度差别大概隻有10 - 100倍,但是磁盤和記憶體的速度大概差了100000倍。由此可見,

L1、L2、L3緩存不命中重新從記憶體中加載資料的代價要遠小于記憶體中頁幀資料不命中所導緻從虛拟記憶體系統中重新加載資料到記憶體中的代價

。是以,虛拟記憶體的緩存需要一個極為複雜精密的算法來盡量減少緩存不命中的情況發生。

當CPU需要尋找資料時,主要需要關注下面幾個問題:

1、目标資料所在的虛拟頁上的資料是否已經加載到記憶體

2、如果已經加載到記憶體中了,具體在哪個頁幀

3、如果尚未加載到記憶體,這個虛拟頁在磁盤哪個位置,然後加載到記憶體中

4、這個虛拟也需要加載到哪個頁幀中,如果頁幀上的資料已經滿了,需要替換哪個頁幀等

1、頁表

作業系統結合了軟體和硬體共同提供功能支援,其中最主要的就是位址翻譯硬體MMU和一個存放在記憶體中的叫做

頁表

的資料結構。頁表負責将虛拟頁面映射到頁幀。MMU每次将虛拟位址轉化為實體位址時,都會讀取頁表。而作業系統負責維護頁表的内容以及在磁盤和DRAM之間複制頁資料。

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體

上圖是一個頁表和虛拟記憶體以及頁幀之間的關系。頁表中每一行記錄被稱為

頁表條目

(PTE),頁表條目由一個有效位和一個n位的位址字段組成。當有效位為1時,表明目前條目所記錄的虛拟頁已經被加載到了頁幀中,條目後半段的位址就是頁幀的起始位址。當有效位為0時,此時有兩種情況,位址字段為空表明目前這個虛拟頁尚未加載磁盤上的資料,是個空虛拟頁,當位址字段不為空,則這個位址指向的是這個虛拟頁在磁盤-記憶體緩存上的起始位置。

2、頁命中

當CPU想要讀取VP2中的一個位元組時,首先MMU通過CPU提供的虛拟位址定位到這個資料所在虛拟頁的頁表條目PTE2,然後發現有效位為1,說明該資料已經加載到頁幀中去了,這個時候直接根據頁幀的起始位址計算出資料的實體位址,然後通過實體尋址将這個資料加載到CPU中去。

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體
3、缺頁

和頁命中相對立的,就是缺頁的情況。

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體

上圖就是一個缺頁的情況。當CPU需要加載VP3中的一個位元組時,MMU首先通過CPU提供的虛拟位址找到該虛拟位址所在的虛拟頁的PTE3。有效位0,位址段不為空表示目前虛拟頁已有資料,但是還沒有加載到記憶體頁幀中。這個時候會觸發一個缺頁異常的ECF(下面是ECF的基本概念介紹)

landexiang:(一)異常控制流​zhuanlan.zhihu.com

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體

觸發ECF後CPU執行缺頁異常處理程式。由于頁幀全都被占用,此時需要選擇一個犧牲頁,假設最終選擇犧牲頁幀3所緩存的VP4,則最終VP3将代替VP4在記憶體中的位置:

加載頁面資料時記憶體突然爆滿_(二)虛拟記憶體

缺頁異常屬于故障ECF,故障在處理完之後應該重新執行觸發故障的指令。是以CPU再次執行資料加載指令,這個時候VP3已經加載到記憶體中了,是以CPU順利的取出的資料。