2009年2月16日 星期一

記憶體跑哪去了?How do I find out who's using all my memory?

        在我思考要用什麼文字當作這篇文章的標題時,看到Keiko丟給我的Ask Leo!網頁,就直接把標題抄下來了。與其想個名詞,不如將整句打上去來得直覺。 
        或許大家會覺得這問題很簡單,只要按下 Ctrl+Alt+Del 便可叫出「工作管理員」(Task Manager),預設就有CPU跟記憶體可以看了。進階一點的玩家可能還會叫出這個畫面,來勾選其他選項來觀察。

image

        回想過去學計組或OS的課程,我們大概知道一支程式在執行期間會將資料暫存於記憶體中,記憶體如果不足,就會開始啟動「恐怖記憶體管理計畫」,計組及OS都花了整整一兩個章節在介紹這些計畫,不過不論用什麼辦法,記憶體不夠就先跟硬碟借一塊來用就對了。既然如此,我就多勾選上圖的「虛擬記憶體大小」選項來看看好了。

image

        如果你認為上圖所寫的「記憶體使用量」跟「虛擬記憶體大小」分別是在physical & virtual memory(hard disk)上,那你就被微軟給騙了!在Ask Leo! 這篇文章中,他介紹我們使用 Process Explorer 去觀察程式的狀態,還教我們叫出 Working Set Size & Virtual Size 兩個欄位。PE 功能之多我這裡不贅述,不過推薦進階玩家們使用,開發這工具的人正是撰寫Windows Internal的作者Mark Russinovich,它可以呈現Windows對記憶體的整體資料結構。另外,如果大家有跟著做的話,會發現:Working Set Size會等於「記憶體使用量」,但Virtual Size卻沒有等於「虛擬記憶體大小」。到底誰講的數字才是對的呢?

        別擔心,其實 PE 有個叫 Private Bytes 的欄位,其數字就會跟「虛擬記憶體大小」一樣,只是這不免再度引人思考:到底哪個數字是被擺在硬碟上的大小?只是想知道OS把我程式的資料擺在哪裡了有必要搞這麼複雜嗎?

        可怕的問題還在後頭。為了測試 x200 的DVMT功能到底是吃掉完整的1G,還是真的能動態將部份記憶體吐還給系統,我寫支程式來測試,用PE的觀察如下圖。

1

        由圖右邊的 Commit Charge 顯示可見到記憶體已被吃掉 3.8 GB,如此一來DVMT確實有發揮其應有的功能,我也不用擔心記憶體平白無故被VGA吃掉1G的情況。奇怪的是,粉紅色的 mem_test.exe,是我執行200次 new doutble [1M] 的結果,大概會用到將近 1.6G 大小的記憶體,為何在 Virtual Size 或 Private Bytes 已經用這麼多了,但 Working Set 仍吃掉 7x MB 呢?而且,如果過一段時間不理他,Working Set 數字還會慢慢變小!另一個更神奇的情況是,如果我繼續再 new 下去,Commit Charge (PF使用量) 甚至可以超過 4G!直到約 4.2 G時程式才會因記憶體不足而被強制中止。

        所有問題的解答,DriverGuru大師在這裡的討論區都有解釋。雖然看完後有了解個大概,但好像仍有一知半解的感覺,所以沒辦法給按END的朋友一個簡單的結論,如果有得道的先進願意提供結論來點化我這愚輩小弟當感激不盡。

2 則留言:

Buffett 提到...

推薦一個好站嚕
Windows Sysinternals

87showmin 提到...

大感謝!原來 PE 就是來自於這裡。