分頁錯誤(page fault,缺頁)
假設你正在讀一本書,翻到某一章,卻發現那一章不在你這本裡——它還在圖書館。你沒辦法繼續讀,除非去把它拿回來。你暫停、走去圖書館、把那一章帶回來、插進你的書裡,然後從你剛剛停下的那句話開始繼續讀。分頁錯誤就是電腦版的這個暫停:程式去拿一頁,而那一頁不在 RAM 裡,於是它必須停下、缺的那頁被取回,接著程式從它原本所在的那道指令繼續。
具體來說,分頁錯誤是當行程參考一頁、而該頁的有效/無效位元說它目前不在實體記憶體時所引發的陷入。「錯誤」這個詞聽起來像是出了問題,但在需求分頁中它是正常、預期內的機制。當參考發生時,記憶體管理硬體偵測到無效位元,於是把控制權轉交給作業系統,而非完成這次存取。作業系統檢視情況,若該頁是行程合法的一部分、只是尚未載入,就走完整的頁錯誤服務流程:在後備儲存上定位該頁、取得一個空閒頁框、把頁讀進來、把分頁表更新為有效,並重新啟動造成錯誤的那道指令。從程式的角度看,那道指令就只是執行了;它完全不知道自己曾被暫停了數毫秒。
為什麼重要:分頁錯誤是虛擬記憶體的脈搏——頁就是靠它在需要的那一刻才被延遲載入的。但每一次必須觸及磁碟的錯誤,跟一次普通的記憶體存取相比都極其昂貴(也許差距達十萬倍),因此分頁錯誤率主導了真實的效能。啟動時發生少數幾次錯誤沒問題;持續不斷的錯誤風暴則代表系統把時間花在等磁碟而不是運算上,在極端情況下就成了輾轉現象。關鍵的區分是:分頁錯誤(頁在磁碟上、可復原)不等於非法記憶體錯誤(位址根本不是你的、通常致命),即使兩者都由同一個有效/無效位元觸發。
某程式執行「load r1, [第 5 頁]」。第 5 頁的項目是無效的,於是 CPU 陷入。作業系統把第 5 頁從置換空間讀進一個頁框、標記為有效,CPU 再次執行同一道「load」指令——這次成功了,r1 取得了它的值。
一次錯誤讓指令暫停,缺頁被取回,同一道指令再被重試。
這裡的「錯誤」並不是程式臭蟲。在需求分頁中,幾乎每一頁的第一次參考依設計都是一次分頁錯誤;只有對行程合法空間之外的位址所發生的錯誤才是真正的錯誤(通常以區段錯誤的形式回報給使用者)。