虛擬記憶體與需求分頁

記憶體過度配置(memory overcommit)

想像一家航空公司賣出的機票多於座位數,賭某些乘客不會出現。大多數航班都沒問題,而航空公司整體載運了更多人。但在每個人都出現的那罕見一天,座位不夠,就有人被擠下飛機。記憶體過度配置就是作業系統下的同一個賭注:它承諾給各行程的記憶體總量超過實際存在的量,賭它們不會在同一時間全都真的用到各自被承諾的全部。

具體來說,過度配置之所以發生,是因為行程往往要求(或被授予)遠多於它們實際觸碰的位址空間——一個程式可能保留一塊巨大的緩衝區,或在一次帶寫入時複製的 fork 之後,名義上擁有父行程記憶體的完整副本,卻從未寫入它。由於頁只有在真正被使用時才消耗真實的頁框(多虧需求分頁與寫入時複製),作業系統便能安全地發出總和超過 RAM 加置換空間的承諾,只要實際使用的總量維持在限度之內。系統追蹤已承諾的記憶體,但把以真實頁框去支撐它這件事,延後到每一頁被觸碰時。這就是為什麼一個行程能成功配置一塊遠大於空閒 RAM 的區塊,而只在稍後使用時,才發現那記憶體是否真的存在。

為什麼重要:過度配置讓一台機器能執行比嚴格記帳所允許之更多、更大的行程,提升了使用率,也讓寫入時複製的 fork 變得實用。但它帶有真實的風險:若行程真的兌現了多於實體記憶體加置換空間所能涵蓋的承諾,作業系統就是超額承諾了,必須採取激烈的手段。某些系統於是殺掉一個行程以回收記憶體(在 Linux 上是記憶體不足終結者,OOM killer);另一些則保守地一開始就拒絕配置。誠實的張力在於:過度配置在常見情況下提升效率,卻可能在最壞情況下造成出人意料、難以預測的失敗——這是一種刻意以確定的安全去換取更佳平均使用率的取捨,很像那班超賣的航班。

在一台只有 6 GB RAM 的機器上,十個行程各自配置一塊 1 GB 的緩衝區,總共承諾 10 GB。大多數行程從不把緩衝區填滿,所以實際使用量維持在 6 GB 以下、全都順利執行。危險在於它們同時填滿的那一天——屆時作業系統必須瘋狂分頁,或殺掉某個行程。

承諾比實際存在更多的記憶體行得通,直到所有人同時兌現的那一刻。

過度配置仰賴大多數承諾從未被完全用到。當這個假設破裂、需求超過 RAM 加置換空間時,結果並不是乾淨地回傳一個錯誤給程式——它可能是記憶體不足終結者終止一個行程,或嚴重的輾轉,兩者都難以預測。

又称
over-allocationovercommitment超額配置過度承諾