記憶體映射檔案(memory-mapped file)
想像你能把圖書館書架上的一本書,當成它的書頁早已攤開在你桌上:你直接讀或在「第 50 頁」上塗寫,而一位館員悄悄讓書架上那本保持同步,只在你翻到某頁時才把它取上你的桌子。記憶體映射檔案(memory-mapped file)就是對檔案施展這個把戲:儲存裝置上的一個檔案被映射進程式的虛擬位址空間,於是程式用一般的記憶體存取來讀寫它,而不必明確呼叫讀/寫。
具體來說,作業系統設好分頁表項,讓行程虛擬位址的一段範圍對應到檔案的內容——但起初那些分頁標示為不存在。程式第一次碰到該範圍中的某個位元組時,一次分頁錯誤只從檔案載入那一頁(把需求分頁套用到檔案上)。讀取回傳檔案資料;寫入修改記憶體中的那頁,而髒掉的頁稍後(或在要求時)寫回檔案。整個檔案永遠不必一次全在記憶體中——只有實際存取到的分頁才佔用頁框,與任何其他分頁式記憶體完全一樣。
為何重要:記憶體映射檔案用同一套分頁機制統合了檔案 I/O 與記憶體存取,既優雅又往往很快。它讓「在行程間共享一個檔案的分頁」變得自然(各自映射同樣的頁框,於是改動立即互相可見——一種乾淨的行程間通訊與共享函式庫機制),也讓你能處理比 RAM 還大的檔案,只把使用中的部分載入。它生動地證明虛擬記憶體根本不真是關於 RAM 對磁碟,而是關於對儲存裝置一種統一、經過翻譯、按需驅動的視角。誠實的提醒:錯誤該花的代價照樣要花,而寫回的時機與一致性需要小心。
一支程式在 16 GiB 的機器上把一個 100 GiB 的日誌檔映射進自己的位址空間,然後跳到第 80,000,000,000 個位元組去讀。只有那個位移附近的幾頁被載入;檔案的其餘部分從不進入 RAM。
檔案變成可定址的記憶體;只有碰到的分頁被載入——以分頁實現的檔案 I/O。
記憶體映射檔案重用了與需求分頁完全相同的「錯誤並載入分頁」機制——這正是更深的重點:對分頁系統而言,「檔案的一頁」與「程式的一頁」是同一類東西,只是由不同的儲存裝置支撐。