[轉]虛擬記憶體,實體記憶體,頁面檔,還有任務管理器

來源鏈結
虛擬記憶體(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的大小就可以計算出位元組數,
這個值可以做為設定頁面檔最小值的一個參考,
而不是用任務管理器進程頁的所有進程的虛擬記憶體大小相加做為頁面檔最小值的參考。

 

  1 comment for “[轉]虛擬記憶體,實體記憶體,頁面檔,還有任務管理器

  1. Abdulrazakpt China Google Chrome Windows
    2015-12-19 at 08:28

    Thanks for the great info dog I owe you bitiygg.

发表评论

电子邮件地址不会被公开。 必填项已用*标注