虛擬記憶體

分頁錯誤(page fault)

想像櫃台人員查「第 412 號房」,發現目錄寫著「尚未建造/在倉儲中」。櫃台人員不能只是聳聳肩——他暫停這位訪客、叫工務班去取回並裝好那個缺失的房間、更新目錄,然後讓訪客像沒事一樣繼續。分頁錯誤(page fault)正是這個暫停並取回的事件:硬體試圖轉換一個位址,發現該頁不在實體記憶體中,便陷入作業系統來處理。

具體來說,每次存取時 MMU 會檢查分頁表項的有效位元。若它是 0,這頁不在任何頁框中,硬體便引發一個分頁錯誤例外,把控制權轉交給作業系統的錯誤處理常式。處理常式弄清楚這頁住在哪(通常在磁碟上)、找一個空閒頁框(若沒有就逐出別的頁,若那頁是髒的就先寫回)、從儲存裝置讀進這頁、更新分頁表項標示為有效並指向新頁框,然後重新啟動引發錯誤的那道指令——這次就成功了。程式渾然不覺地繼續。違反保護也會引發錯誤,但那一種通常是終止程式而非修好什麼。

為何重要:分頁錯誤讓程式能用比實際存在還多的記憶體、並在完全載入前就開始執行——但它們極其昂貴。一次從磁碟取回是數百萬個 CPU 週期;從 SSD 取回,也還要數萬個。少數幾次錯誤是看不見的,但一個不斷引發錯誤的程式就是在輾轉,可能慢上數千倍。所以分頁錯誤既是讓需求分頁成為可能的功能,同時也是效能最糟糕的遭遇之一——誠實地提醒我們,虛擬記憶體的便利並非免費。

程式第一次碰一個剛配置的分頁。它的 PTE 有效位元是 0,於是分頁錯誤陷入作業系統,作業系統對應進一個清零的頁框並重新啟動該指令——程式完全沒察覺這段繞路。

一次分頁錯誤:偵測缺頁、取回分頁、修好分頁表、重試指令。

並非所有分頁錯誤都會碰磁碟。「次要」錯誤只是對應一個已常駐或清零的分頁(便宜);「主要」錯誤則必須從儲存裝置讀取(非常昂貴)。把兩者搞混,會讓虛擬記憶體聽起來比它通常的樣子還慢。

又稱
page miss缺頁