程序最小化后释放了很多的内存的原因
程序最小化后釋放了很多的內(nèi)存的原因
http://soartomato.iteye.com/blog/726135- 博客分類(lèi):?
- expr
偶然發(fā)現(xiàn)程序最小化后在task manager中的mem usage的數(shù)值會(huì)有大幅度的下降,本以為自己的程序有問(wèn)題,其實(shí)這個(gè)是windows內(nèi)存管理策略的原因(FIFO or LRU),轉(zhuǎn)載一個(gè)非常不錯(cuò)的文章,對(duì)這個(gè)問(wèn)題有著詳細(xì)的解釋。原文網(wǎng)址如下:http://astarring.iteye.com/blog/525692
?
Task Manager的Mem Usage數(shù)據(jù) 與 VM Size
下面是我分析這問(wèn)題的一些思路,希望對(duì)對(duì)這個(gè)問(wèn)題感興趣的朋友有所幫助:?
Q: Is .NET Alone??
A: Nope! 前面Saucer說(shuō)過(guò)了,這不是.NET的問(wèn)題,所有Windows程序都有類(lèi)似的行為。例如下面的C程序:?
void main { while(1); } //死循環(huán),便于我們察看Task Manager?
初次運(yùn)行在我的機(jī)器上Mem Usage是632K,把Console最小化以后再恢復(fù),Mem Usage變成了36K。顯然,這不是一個(gè).NET獨(dú)有的問(wèn)題,而是Windows Memory Management的問(wèn)題。那么和.NET的GC機(jī)制也不會(huì)有太大的關(guān)系——雖然問(wèn)題的表現(xiàn)形式很容易讓人聯(lián)想到GC。?
Q: How much memory does my program use??
http://www.mscto.com?
A: 回答這個(gè)問(wèn)題并不容易。先來(lái)看看操作系統(tǒng)虛擬內(nèi)存管理的一些基本概念:每個(gè)Windows進(jìn)程都擁有4G的地址空間,但是你的機(jī)器顯然沒(méi)有4G的物理內(nèi) 存。在多任務(wù)環(huán)境下,所有進(jìn)程使用的內(nèi)存總和可以超過(guò)計(jì)算機(jī)的物理內(nèi)存。在特定的情況下,進(jìn)程的一部分可能會(huì)從物理內(nèi)存中刪除而被暫存在硬盤(pán)的文件里 (pagefile),當(dāng)進(jìn)程試圖訪問(wèn)這些被交換到pagefile里的內(nèi)存的時(shí)候,系統(tǒng)會(huì)產(chǎn)生一個(gè)缺頁(yè)中斷(page fault),這時(shí)候Windows內(nèi)存管理器會(huì)負(fù)責(zé)把對(duì)應(yīng)的內(nèi)存頁(yè)重新從硬盤(pán)調(diào)入物理內(nèi)存。?
在某個(gè)時(shí)間內(nèi),一個(gè)進(jìn)程可以直接訪問(wèn)到的物理內(nèi)存(不發(fā)生缺頁(yè)中斷)叫做這個(gè)進(jìn)程的 Working Set ;而一個(gè)進(jìn)程從4G的地址空間當(dāng)中實(shí)際分配(commit)了的、可訪問(wèn)的內(nèi)存稱(chēng)為 Committed Virtual Memory 。Committed VM可能存在于Page File當(dāng)中,WorkingSet則一定位于物理內(nèi)存。?
所以要回答上面的問(wèn)題先要反問(wèn)一句:What're you talking about? Physical Memory or Committed Memory??
Q: What is this "Mem Usage" data? 軟件開(kāi)發(fā)網(wǎng)?
A: From Task Manager Help: In Task Manager, the current Working Set of a process, in kilobytes. 軟件開(kāi)發(fā)網(wǎng)
Mem Usage這個(gè)名字多少有些誤導(dǎo)。它只表示這個(gè)進(jìn)程當(dāng)前占用的物理內(nèi)存,也就是WorkingSet。WorkingSet不表示進(jìn)程當(dāng)前“占用”的所有 虛擬內(nèi)存,該進(jìn)程可能還有一部分?jǐn)?shù)據(jù)被交換到pagefile當(dāng)中。這些數(shù)據(jù)只有在被訪問(wèn)的時(shí)候才會(huì)被加載到物理內(nèi)存。?
Task Manager有另一列數(shù)據(jù):VM Size,表示了一個(gè)進(jìn)程分配的虛存(Committed Visual Memory)——實(shí)際的定義要比這個(gè)復(fù)雜一些,但這個(gè)定義對(duì)我們目前分析的問(wèn)題已經(jīng)足夠了。以前面的C程序?yàn)槔?#xff0c;在最小化前后的VM Size都是176K,并沒(méi)有變化。?
所以,結(jié)論很簡(jiǎn)單: 當(dāng)一個(gè)Windows程序被最小化的時(shí)候,Windows內(nèi)存管理器把該進(jìn)程的WorkingSet減到最小(根據(jù)先進(jìn)先出FIFO或者最近最少使用 LRU),把大部分?jǐn)?shù)據(jù)交換到pagefile里。 這很容易理解:我們通常總是希望為前臺(tái)的應(yīng)用程序留出更多物理內(nèi)存,從而具有更好的性能。 當(dāng)該程序從最小化恢復(fù)的時(shí)候,Windows也不會(huì)完全加載程序的所有虛存,只是加載了必要的部分。 這也很容易理解:程序啟動(dòng)階段的代碼通常在啟動(dòng)之后很少訪問(wèn)(對(duì).NET程序尤其如此,向fusion這樣的模塊在程序正常加載之后如果沒(méi)有用到 Reflection通常用不到)。?
Q: So, Do we want a smaller workingset, or a larger one??
A: It depends. Conventional Wisdom tells us: The smaller, the better. 但是在虛存的問(wèn)題上卻沒(méi)這么簡(jiǎn)單。如果WorkingSet太小,程序運(yùn)行過(guò)程中會(huì)產(chǎn)生很多缺頁(yè)中斷,這會(huì)嚴(yán)重影響程序的性能。另一方 面,WorkingSet太大會(huì)浪費(fèi)“寶貴的”物理內(nèi)存,降低整個(gè)系統(tǒng)的性能。 通常情況下(除非是對(duì)性能非常敏感的應(yīng)用程序,并且你對(duì)Windows的內(nèi)存管理了如指掌),建議不要在程序中自己調(diào)整WorkingSet的大小,而把 這個(gè)任務(wù)交給Windows內(nèi)存管理器。調(diào)整的方法Saucer有提到: SetProcessWorkingSetSize ();?
Q: Final Question, Does my program really occupy that much physical memory? http://www.mscto.com?
A: 這個(gè)問(wèn)題看上去土了點(diǎn)——那個(gè)數(shù)字明明白白的寫(xiě)在Task Manager里面。?
sam1111 用vadump檢查的結(jié)果顯示進(jìn)程WorkingSet減小的主要原因是很多DLL在從最小化恢復(fù)的時(shí)候沒(méi)有被加載到物理內(nèi)存。我們知道DLL的一個(gè)特點(diǎn) 是代碼共享,以NTDLL.DLL為例,整個(gè)Windows系統(tǒng)的幾乎所有應(yīng)用程序(具體地說(shuō),Win32子系統(tǒng)的所有程序)都需要引用 NTDLL.DLL,如果每人一份,光這個(gè)文件就的占用幾十兆內(nèi)存。Windows地解決辦法是只在物理內(nèi)存中保存一份NTDLL.DLL的COPY,所 有引用這個(gè)DLL的程序都把這一份COPY映射到自己的內(nèi)存空間里面,共享NTDLL.DLL的代碼段(每個(gè)進(jìn)程的數(shù)據(jù)段仍然是獨(dú)立的)。所以雖然 NTDLL.DLL的大小被計(jì)算在你的程序的WorkingSet里面,但是從你的程序中去掉對(duì)這個(gè)DLL的引用并不會(huì)真的釋放多少物理內(nèi)存——你不用, 別人還在用呢!?
所以,你的程序“獨(dú)占”的物理內(nèi)存遠(yuǎn)沒(méi)有Mem Usage所表示的那么多,需要從Mem Usage里面扣除很多Shared Code Page (vadump里面可以看到)。 http://www.mscto.com?
結(jié)論?不要參考Task Manager的Mem Usage數(shù)據(jù),那個(gè)數(shù)據(jù)的大小對(duì)程序性能沒(méi)有直接影響。 用Perfomence Monitor里面與.NET相關(guān)的Counter要容易、準(zhǔn)確的多。
總結(jié)
以上是生活随笔為你收集整理的程序最小化后释放了很多的内存的原因的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: vc6下c++编译器通不过,c编译器通过
- 下一篇: VB.NET程序如何巧妙释放内存