Windows工做集內存

Windows任務管理器默認狀況下,「內存(私人工做集)」列處於選中狀態。app

私人工做集是工做集的一個子集,它是描述每一個進程所使用的內存數量的技術術語。私人工做集專門描述了某個進程正在使用的且沒法與其餘進程共享的內存數量。dom


內存 - 工做集是私人工做集中的內存數量與進程正在使用且能夠由其餘進程共享的內存數量的總和。
內存 - 峯值工做集是進程所使用的工做集內存的最大數量。
內存 - 工做集增量是進程所使用的工做集內存中的更改量。
內存 - 提交大小是爲某進程使用而保留的虛擬內存的數量。
內存 - 頁面緩衝池是能夠寫入其餘存儲媒體(例如硬盤)的某個進程的承認虛擬內存數量。
內存 - 非頁面緩衝池是沒法寫入其餘存儲媒體的某個進程的承認虛擬內存數量。ide

 

一 SetProcessWorkingSetSize 的工做原理函數

看看這個API                       SetProcessWorkingSetSizepost

這是從MSDN摘下的原話性能

Using the SetProcessWorkingSetSize function to set an application's minimum and maximum working set sizes does not guarantee that the requested memory will be reserved, or that it will remain resident at all times. When the application is idle, or a low-memory situation causes a demand for memory, the operating system can reduce the application's working set. An application can use the VirtualLock function to lock ranges of the application's virtual address space in memory; however, that can potentially degrade the performance of the system.ui

使用這個函數來設置應用程序最小和最大的運行空間,只會保留須要的內存。當應用程序被閒置或系統內存過低時,操做系統會自動調用這個機制來設置應用程序的內存。應用程序也可使用 VirtualLock 來鎖住必定範圍的內存不被系統釋放。this

When you increase the working set size of an application, you are taking away physical memory from the rest of the system. This can degrade the performance of other applications and the system as a whole. It can also lead to failures of operations that require physical memory to be present; for example, creating processes, threads, and kernel pool. Thus, you must use the SetProcessWorkingSetSize function carefully. You must always consider the performance of the whole system when you are designing an application.url

當你加大運行空間給應用程序,你可以獲得的物理內存取決於系統,這會形成其餘應用程序下降性能或系統整體下降性能,這也可能致使請求物理內存的操做失敗,例如:創建 進程,線程,內核池,就必須當心的使用該函數。spa

========================

事實上,使用該函數並不能提升什麼性能,也不會真的節省內存。

由於他只是暫時的將應用程序佔用的內存移至虛擬內存,一旦,應用程序被激活或者有操做請求時,這些內存又會被從新佔用。若是你強制使用該方法來 設置程序佔用的內存,那麼可能在必定程度上反而會下降系統性能,由於系統須要頻繁的進行內存和硬盤間的頁面交換。


BOOL SetProcessWorkingSetSize(
HANDLE hProcess,
SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize
);


將 2個 SIZE_T 參數設置爲 -1 ,便可以使進程使用的內存交換到虛擬內存,只保留一小部分代碼

1 。當咱們的應用程序剛剛加載完成時,可使用該操做一次,來將加載過程不須要的代碼放到虛擬內存,這樣,程序加載完畢後,保持較大的可用內存。

2.程序運行到必定時間後或程序將要被閒置時,可使用該命令來交換佔用的內存到虛擬內存。

二 區分物理內存、虛擬內存、Working Set(Memory)、Memory

如下來自:http://blog.joycode.com/qqchen/archive/2004/03/17/16434.aspx

這個問題在CSDN上碰到好幾回,我每次都只給出了簡單的答案:不要參考Task Manager的Mem Usage數據,那個數據的大小對程序性能沒有直接影響。
下面是我分析這問題的一些思路,但願對對這個問題感興趣的朋友有所幫助

Q: Is .NET Alone?
A: Nope! 前面Saucer說過了,這不是.NET的問題,全部Windows程序都有相似的行爲。例以下面的C程序:
void main { while(1); }   //死循環,便於咱們察看Task Manager
初次運行在個人機器上Mem Usage是632K,把Console最小化之後再恢復,Mem Usage變成了36K。顯然,這不是一個.NET獨有的問題,而是Windows Memory Management的問題。那麼和.NET的GC機制也不會有太大的關係——雖然問題的表現形式很容易讓人聯想到GC。

Q: How much memory does my program use?
A: 回答這個問題並不容易。先來看看操做系統虛擬內存管理的一些基本概念:每一個Windows進程都擁有4G的地址空間,可是你的機器顯然沒有4G的物理內存。在多任務環境下,全部進程使用的內存總和能夠超過計算機的物理內存。在特定的狀況下,進程的一部分可能會從物理內存中刪除而被暫存在硬盤的文件裏(pagefile),當進程試圖訪問這些被交換到pagefile裏的內存的時候,系統會產生一個缺頁中斷(page fault),這時候Windows內存管理器會負責把對應的內存頁從新從硬盤調入物理內存。
在某個時間內,一個進程能夠直接訪問到的物理內存(不發生缺頁中斷)叫作這個進程的Working Set;而一個進程從4G的地址空間當中實際分配(commit)了的、可訪問的內存稱爲Committed Virtual Memory。Committed VM可能存在於Page File當中,WorkingSet則必定位於物理內存。
因此要回答上面的問題先要反問一句:What're you talking about? Physical Memory or Committed Memory?

Q: What is this "Mem Usage" data?
A: From Task Manager Help: In Task Manager, the current Working Set of a process, in kilobytes. 
Mem Usage這個名字多少有些誤導。它只表示這個進程當前佔用的物理內存,也就是WorkingSet。WorkingSet不表示進程當前「佔用」的全部虛擬內存,該進程可能還有一部分數據被交換到pagefile當中。這些數據只有在被訪問的時候纔會被加載到物理內存。
Task Manager有另外一列數據:VM Size,表示了一個進程分配的虛存(Committed Visual Memory)——實際的定義要比這個複雜一些,但這個定義對咱們目前分析的問題已經足夠了。之前面的C程序爲例,在最小化先後的VM Size都是176K,並無變化。
因此,結論很簡單:當一個Windows程序被最小化的時候,Windows內存管理器把該進程的WorkingSet減到最小(根據先進先出FIFO或者最近最少使用LRU),把大部分數據交換到pagefile裏。這很容易理解:咱們一般老是但願爲前臺的應用程序留出更多物理內存,從而具備更好的性能。當該程序從最小化恢復的時候,Windows也不會徹底加載程序的全部虛存,只是加載了必要的部分。這也很容易理解:程序啓動階段的代碼一般在啓動以後不多訪問(對.NET程序尤爲如此,向fusion這樣的模塊在程序正常加載以後若是沒有用到Reflection一般用不到)。

Q: So, Do we want a smaller workingset, or a larger one?
A: It depends. Conventional Wisdom tells us: The smaller, the better. 可是在虛存的問題上卻沒這麼簡單。若是WorkingSet過小,程序運行過程當中會產生不少缺頁中斷,這會嚴重影響程序的性能。另外一方面,WorkingSet太大會浪費「寶貴的」物理內存,下降整個系統的性能。 一般狀況下(除非是對性能很是敏感的應用程序,而且你對Windows的內存管理了如指掌),建議不要在程序中本身調整WorkingSet的大小,而把這個任務交給Windows內存管理器。調整的方法Saucer有提到: SetProcessWorkingSetSize();

Q: Final Question, Does my program really occupy that much physical memory?
A: 這個問題看上去土了點——那個數字明明白白的寫在Task Manager裏面。
sam1111用vadump檢查的結果顯示進程WorkingSet減少的主要緣由是不少DLL在從最小化恢復的時候沒有被加載到物理內存。咱們知道DLL的一個特色是代碼共享,以NTDLL.DLL爲例,整個Windows系統的幾乎全部應用程序(具體地說,Win32子系統的全部程序)都須要引用NTDLL.DLL,若是每人一份,光這個文件就的佔用幾十兆內存。Windows地解決辦法是隻在物理內存中保存一份NTDLL.DLL的COPY,全部引用這個DLL的程序都把這一份COPY映射到本身的內存空間裏面,共享NTDLL.DLL的代碼段(每一個進程的數據段仍然是獨立的)。因此雖然NTDLL.DLL的大小被計算在你的程序的WorkingSet裏面,可是從你的程序中去掉對這個DLL的引用並不會真的釋放多少物理內存——你不用,別人還在用呢!
因此,你的程序「獨佔」的物理內存遠沒有Mem Usage所表示的那麼多,須要從Mem Usage裏面扣除不少Shared Code Page (vadump裏面能夠看到)。

結論?不要參考Task Manager的Mem Usage數據,那個數據的大小對程序性能沒有直接影響。用Perfomence Monitor裏面與.NET相關的Counter要容易、準確的多

相關文章
相關標籤/搜索