虛擬記憶體與記憶體映射

虛擬記憶體(virtual memory)

想像一棟巨大公寓裡的每位住戶,都以為自己住在 1 號公寓,各自擁有一套私有、重新編號、鄰居絕對走不進來的房間。他們不知道、也不在乎自己的房間實際在哪一層樓;一位大樓管理員默默替每位住戶保管一份私有的地圖。虛擬記憶體對程式來說正是這個把戲:每個執行中的程式都拿到一套自己專屬、廣大、乾淨且私有的位址,而作業系統暗中保管一份從這些位址到真實晶片的對映表。

具體來說,你的 C 程式所用的位址——你從 &x 看到的號碼、malloc() 還給你的位置——都是虛擬位址(virtual address)。它們不是 RAM 晶片上的實體位置。當程式碰觸一個虛擬位址時,硬體會即時根據作業系統建好的表,把它轉譯成實體位址(physical address)。這帶來三大好處:隔離(一個程式無法指名、讀取或破壞另一個程式的記憶體,因為它們的定址空間是各自獨立的地圖)、一段連續大空間的錯覺(程式看到一整段井然有序的位址,即使背後真正的 RAM 是零散且共用的),以及假裝記憶體比機器實際擁有的還多(很少用到的分頁可以先停放到磁碟上)。

誠實地說,虛擬記憶體不是什麼。它不會讓電腦變快,也不等於「置換空間(swap)」——置換只是虛擬記憶體所促成的其中一件事。轉譯也不是免費的:它需要硬體(MMU 與 TLB)成本,偶爾還有昂貴的分頁錯誤。但隔離與這個簡單的私有定址空間模型如此寶貴,以至於今天幾乎每一個通用作業系統都建立在虛擬記憶體之上。

把同一支程式跑兩次;兩份副本都可能從 printf("%p\n", (void*)&x) 印出相同的位址,例如 0x55a3c1d04010。它們不會撞在一起,因為那個 0x55a3c1d04010 是各行程私有的虛擬位址——作業系統把這兩者對映到不同的實體 RAM。

相同的虛擬位址,不同的實體 RAM——這就是核心的錯覺。

虛擬記憶體不是「免費多得到的記憶體」,也不是置換空間的同義詞。它是一種位址對映機制;把分頁置換到磁碟只是它的一種用途。關掉置換並不會關掉虛擬記憶體。

又稱
VM虛擬定址空間