如果只從程式的角度看,記憶體好像很單純。宣告變數、配置 buffer、呼叫 malloc(),拿到一個位址,接著讀寫它。可是這個位址通常不是實體 RAM 上真正的位置,而是虛擬位址。Linux 讓每個 process 都活在自己的虛擬位址空間裡,process 看到的是一套被整理過的假象。
這個假象很重要。第一個好處是隔離。A process 看到的 0x400000,和 B process 看到的 0x400000,可以完全指向不同的實體頁面。它們不會因為位址數字一樣就互相踩到。第二個好處是彈性。kernel 可以等到真的需要時才配置實體頁面,也可以把檔案映射到記憶體,甚至把暫時不用的頁面換到 swap。
所以虛擬記憶體不是「把硬碟當記憶體」這麼窄的概念。比較準確地說,它是一層位址抽象:process 使用虛擬位址,CPU 藉由 MMU 和 page table 把它轉成實體位址。這個轉換讓 Linux 可以同時做到隔離、延遲配置、檔案映射、權限控管和共享記憶體。
一個 process 的虛擬位址空間通常會分成幾段:程式碼、唯讀資料、可寫資料、heap、共享函式庫、mmap 區域、stack。這些區域不一定在實體 RAM 裡連續,甚至不一定都已經真的配置 RAM。它們只是 process 目前可以使用或可能使用的範圍。
理解這件事後,很多指標就比較不容易誤讀。例如 VSZ 很大,只代表虛擬位址空間很大,不代表真的吃掉那麼多 RAM。RSS 才比較接近目前實際常駐在 RAM 的頁面數量,但它也不等於「這個 process 獨占的記憶體」,因為共享頁面會讓事情變複雜。
下一篇會接著看 VMA。虛擬位址空間不是一整塊平的東西,kernel 會把它切成多個 Virtual Memory Area,分別記錄用途、權限和來源。看懂 VMA,就能更清楚 mmap()、shared library、heap 和 stack 在 kernel 眼中長什麼樣子。