由於所有用戶進程總的虛擬地址空間比可用的物理內存大很多,因此只有最常用的部分才與物理頁幀關聯。這不是問題,因為大多數程序只占用實際可用內存的一小部分。
在將磁盤上的數據映射到進程的虛擬地址空間的時,內核必須提供數據結構,以建立虛擬地址空間的區域和相關數據所在位置之間的關聯。例如,在映射文本文件時,映射的虛擬內存區必須關聯到文件系統的硬盤上存儲文件內容的區域。如圖所示:
當然,給出的是簡化的圖,因為文件數據在硬盤上的存儲通常並不是連續的,而是分布到若干小的區域。內核利用address_space數據結構,提供一組方法從后備存儲器讀取數據。例如,從文件系統讀取。因此address_space形成了一個輔助層,將映射的數據表示為連續的線性區域,提供給內存管理子系統。
按需分配和填充頁稱為按需調頁法。它基於處理器和內核之間的交互,使用的各種數據結構如圖所示:
過程如下:
CPU將一個虛擬內存空間中的地址轉換為物理地址,需要進行兩步(如下圖):
首先,將給定一個邏輯地址(其實是段內偏移量,這個一定要理解!!!),CPU要利用其段式內存管理單元,先將為個邏輯地址轉換成一個線程地址,
其次,再利用其頁式內存管理單元,轉換為最終物理地址。
這樣做兩次轉換,的確是非常麻煩而且沒有必要的,因為直接可以把線性地址抽像給進程。之所以這樣冗余,Intel完全是為了兼容而已。
- 進程試圖訪問用戶地址空間中的一個內存地址,利用上面的線性地址去查找頁表,確定對應的物理地址,但使用的頁表無法確定物理地址(物理內存中沒有關聯頁)
- 處理器接下來觸發一個缺頁異常,發送到內核。
- 內核會檢查負責缺頁區域的進程地址空間數據結構,找到適當的后備存儲器,或者確認該訪問實際上是不正確的(未映射,未使用)
- 分配物理內存頁,並從后備存儲器讀取所需數據填充。
- 借助於頁表將物理內存頁並入到用戶進程的地址空間,應用程序恢復執行。
這些操作對用戶進程是透明的。換句話說,進程不會注意到頁是實際在物理內存中,還是需要通過按需調頁加載。
在整個過程中可能需要解決以下幾個問題:
1)系統如何感知進程當前所需頁面不在主存(頁表機制);
2)當發現缺頁時,如何把所缺頁面調入主存(缺頁中斷機構);
3)在置換頁面時,根據什么策略選擇欲淘汰的頁面(置換算法)。
頁表機制
狀態位(中斷位):標識該頁是否在內存(0或1);
訪問位:標識該頁面的近來的訪問次數或時間(換出);
修改位:標識此頁是否在內存中被修改過;
外存地址:記錄該頁面在外存上的地址,即(外存而非內存的)物理塊號。
缺頁中斷機制
程序在執行時,首先檢查頁表,當狀態位指示該頁不在主存時,則引起一個缺頁中斷發生,其中斷執行過程與一般中斷相同:
保護現場(CPU環境);
中斷處理(中斷處理程序裝入頁面);
恢復現場,返回斷點繼續執行。
置換算法
FIFO
LRU
LFU