虛擬記憶體,實體記憶體,頁面檔案,還有工作管理員

查志強發表於2015-01-07

【原文:http://blog.csdn.net/lincyang/article/details/6023566

虛擬記憶體(Virtual Memory)是Windows管理所有可用記憶體的方式。
對於32位Windows系統,每個程式所用到的虛擬記憶體地址從0到2^32-1,總容量4GB,
其中2GB是與作業系統以及其他所有程式所共享,
另外2GB分派給程式獨佔(這就是常說的32位Windows中一個程式最多能用2G記憶體的由來)。

4GB虛擬地址空間(Virtual Address Space,VAS)中,2GB的程式獨佔VAS是程式隔離的,
換句話說,每個程式都可以從RAM或者硬碟上對映到屬於自己的2GB VAS。
所以雖然32位Windows每個程式最多隻能獲得4GB可用虛擬記憶體,
但是所有程式總和可以使用總量超過4GB的虛擬記憶體。
可惜XP只支援4GB RAM,也就是說超出部分一定得靠頁面檔案補足;
而比如2003企業版通過PAE支援32GB RAM,可以減少頁面檔案的用量。
(但單個程式最多仍然只有4GB虛擬記憶體地址空間,而不是32GB)

所以,一個簡單的計算示例:
三個程式最多能用掉多少VAS?
2GB(共享)+2GB(獨佔)×3=8GB

這4GB的虛擬地址空間,按照4KB的大小進行分頁(page),
然後以頁為單位對映到實際儲存單元中,包括:
·實體記憶體(RAM)
·頁面檔案(Page File,在Win9x中稱為交換檔案Swap File,即win386.swp)
·其他檔案自身(比如一些長時間未活動的程式的exe檔案自身)
可見,通常人們所說的虛擬記憶體實際上只是指其中的頁面/交換檔案而已,
這是對虛擬記憶體的一個錯誤的理解。
虛擬記憶體≠頁面檔案
RAM中除了儲存最近讀寫的檔案快取(File Cache,相當於Win9x中的Vcache)
主要用來儲存正在使用的程式程式碼和資料,
當RAM資源緊張,或者有程式碼或資料長時間未使用時,
XP通常會將非活躍程式碼所在的地址頁對映回程式檔案(exe、dll等),
將資料所在的地址頁對映到頁面檔案(pagefile.sys)中並拷貝資料,
然後將它們本來佔用的RAM空間釋放。
這個過程稱為頁出(Page Out)。
當系統讀取某個虛擬記憶體地址,而該地址所在的頁不在RAM中時,
將產生一個頁面錯誤(Page Fault)中斷,
告訴系統從頁面檔案或者程式檔案中取回包含該地址的虛擬記憶體頁,
即將內容拷回到RAM並建立新的虛擬地址對映,並將頁面檔案中對應部分標記為未使用,這個過程就是頁入(Page In)。
頁入成功的話就是一個Valid Page Fault,否則就是Invalid Page Fault。
前者非常普遍,(可以在工作管理員的程式頁監視到)
而後者是由程式或硬體錯誤引起,
如果發生在程式上會導致非法操作,如果是系統自身則很可能藍屏。

記憶體用量可以在工作管理員的效能頁中看到。
其中實體記憶體的總量、可用數等是指安裝的RAM容量和剩餘RAM容量,
而記憶體使用或者提交更改的總量和限制是指虛擬記憶體的Commit Limit和Committed Bytes,
可以理解成系統可以使用的虛擬記憶體總量和當前使用量,
其中總量是由RAM大小+頁面檔案大小決定的。

而在工作管理員的程式頁中,“記憶體使用”和“虛擬記憶體大小”造成的誤解很多,
而實際上,這兩個值是對應效能監視器中該程式的Working Set和Private Bytes,

Working Set是指一個程式的4GB虛擬地址空間中被對映到RAM中的部分的大小,
通常是該程式的虛擬記憶體中的活躍部分。
表面看來這個表述和“程式佔用的RAM大小”沒有太大區別,
但至少有兩種情況導致了例外的發生:
第一種是這部分虛擬記憶體如果是屬於2G的系統共享虛擬記憶體,
那麼它對映到的RAM地址可能和其他程式有重複,計算多個程式佔用RAM總和就不正確,
使得所有程式的Working Set之和比實際佔用RAM要大。
第二種是一個程式中可能有同一段RAM內容的多個引用,比如一個檔案被loop多次,
此時虛擬空間中會有多段地址被對映到同一段RAM上,
從而造成該程式的Working Set比實際佔用RAM要大。

Private Bytes是一個程式的2GB獨佔虛擬地址空間中用到的部分的大小,
無論這部分是在RAM中還是在頁面檔案中,甚至是在exe、dll等檔案中。
所以,工作管理員程式頁中的虛擬記憶體絕對不反映pagefile.sys的用量。

所以,工作管理員無論是程式頁還是效能頁都不能直接反映pagefile的使用情況,
諸如“關掉pagefile還能看到虛擬記憶體”之類的疑問,應該很清楚了。

下面是一個簡單圖示,
兩個程式,各自擁有2G獨佔VAS,共同擁有2G共享VAS,
W代表對映到RAM中的部分(Working Set),P代表頁出的部分。

      0 …………………2GB獨佔記憶體……………… 2G ………2GB共享記憶體……… 4G
程式1 |--PPPP---------------WW-----PPPP--------|
         ////              ||    ////
             ////          ||    ////
            ////          ||        ||||     |--PPPPPPPPPPPP--WWWWWWWW--|
          exe2 exe1 dll   RAMemory pagefile.sys ||||||||||||   ||||||||
          ||||    /// ///   /     || |     共享核心/dll等 共享RAM空間
程式2 |-PPPP------PPP---WW--WW------PP----P----|

然後,工作管理員的程式頁中的“記憶體”就是上圖中的W,
所以所有程式的記憶體項加起來肯定比實際用的RAM大,因為有共享部分
此外還有重複引用,比如上圖中程式2獨佔記憶體中第二和第三個W指向同一段RAM空間。

而工作管理員程式頁中的“虛擬記憶體”就是上圖中右半部分,“獨佔VAS”。
可見pagefile只是其中的一部分,而RAM,只要用於獨佔VAS,一樣計入了該處“虛擬記憶體”


最後,實際的頁面檔案用量(pagefile.sys中實際使用部分),
可以在效能監視中看到,即Paging File下的% Usage和% Usage Peak
配合當前pagefile.sys的大小就可以計算出位元組數,
這個值可以做為設定頁面檔案最小值的一個參考,
而不是用工作管理員程式頁的所有程式的虛擬記憶體大小相加做為頁面檔案最小值的參考。

 

這篇文章轉了好幾手了,不知道源頭在哪了,對不住了。。。


相關文章