虛擬記憶體與記憶體映射

分頁錯誤(page fault)

分頁錯誤(page fault)是當你的程式碰觸一個其分頁目前無法照請求方式使用的虛擬位址時所發生的事——別被這名字嚇到,大多數分頁錯誤完全正常、在預期之內,並不是當機。它就像管理員發現被要求的房間還沒準備好,於是先讓住戶暫停,再去把它取來或備好。

在機制上,當 MMU 試著轉譯一個位址、卻發現該頁的存在位元是 0(或此次存取違反該頁的權限)時,它無法完成存取,於是引發一個 CPU 例外——也就是分頁錯誤——並陷入作業系統。作業系統檢視想要做什麼並做決定。若該頁確實缺席但理應存在(從未載入、或被置換到磁碟),作業系統就配置一個頁框、必要時載入資料、修好分頁表項,並悄悄重新執行那條出錯的指令,彷彿什麼都沒發生。若這次存取其實真的非法(野指標指進未對映區域、或寫入唯讀記憶體),作業系統會拒絕,並把一個錯誤交付給程式——在 Unix 上,那會以記憶體區段錯誤背後的 SIGSEGV 浮現。

所以同一套機制服務兩種非常不同的結果:可服務的錯誤(需求分頁、寫入時複製與置換的基礎,作業系統把事情修好後繼續)與致命的錯誤(一個臭蟲,程式被終止)。認清這個區別很關鍵:一支程式在正常運作期間可能發生數百萬次無害的分頁錯誤。當機只是其中一種特殊、非法的情形。

在 malloc() 給你 1 MiB 之後,那些位元組其實還沒真的在 RAM 裡。寫入 buf[0] = 1 碰到一頁尚無實體支撐的分頁,造成一次分頁錯誤,作業系統悄悄對映進一個全新的零頁框,讓寫入完成——這是正常、可服務的錯誤,不是當機。

大多數分頁錯誤是例行公事;只有非法的那種會當掉。

分頁錯誤不等於記憶體區段錯誤。分頁錯誤是硬體機制;作業系統可能服務它(正常),或在存取非法時把它變成終結程式的記憶體區段錯誤(SIGSEGV)。大多數分頁錯誤從不會傳到你的程式。

又称
page fault exception缺頁錯誤