內存工作設置(工作集)、提交大小概念簡述(超詳細,很多相關文章)


內存工作設置(工作集)、提交大小概念簡述

前言

Windows7的任務管理器(以中文版為例)里面"進程"Tab頁的列里面跟內存相關的展示項有7項(分頁池和非頁面緩沖池跟內核內存有關,暫不討論),做軟件工程師多年,大家真的懂任務管理器中這些內存相關的列嗎?譬如什么工作集,專用工作集等等,另外像其它的一些常用工具,譬如ProcessExplorer里面可能又是叫Working Set,Private Bytes。

另外像SetProcessWorkingSet,EmptyWorkingSet這些函數真的是洪水猛獸,完全不能使用嗎?本文將簡單討論下這些問題,另外簡單介紹下VMMap工具的使用。

名詞解釋

先進行一下名詞解釋,其實這個地方容易搞混的一個原因也是不同的工具的描述不一樣,導致有些混亂,因此這里先把這些概念統一下,然后再進行解釋(WS:Working Set的簡稱,none:表示無對應的顯示選項)。

Win7任務管理器中名稱 Process Explorer中名稱 VMMap中的名稱
工作設置(內存) Working Set Total WS
內存(專用工作集) WS Private Private WS
提交大小 Private Bytes Private(or Private Bytes)
內存(共享工作集)* WS Shareable Shareable WS
none WS Shared Shared WS
none Virtrual Size Size
none none Committed

*Win10上面有共享工作集的展示

工作設置(內存)/Working Set/Total WS: 專用(私有)工作集(當前進程獨占)中的物理內存數量與進程正在使用且可以和其他進程共享的物理內存數量的總和,因此可以這么理解,該值就是該進程所占用的總的物理內存,但是這個值是由兩部分組成,即"專用工作集"和"共享工作集"(Win10的任務管理器里面可以看到共享工作集)。在深入解析Windows操作系統里面是這樣描述的:物理上駐留在內存中的那一部分子集稱為工作集(Working Set)。

峰值工作設置(內存): 進程的工作設置(內存)的最值,可以這么理解,因為工作設置(內存)是波動的,這個項專門記錄最大的那個值。

內存(專用工作集)/WS Private/ Private WS: 工作集的子集,它專門描述某個進程正在使用且無法與其他進程共享的物理內存值。這個值對於一個進程來說也是最重要的,它代表了一個進程到底獨占了多少物理內存。

內存(共享工作集)/ WS Shareable/ Shareable WS: 進程和可以和別的進程共享的物理內存值(注意:是可以共享的,不一定共享了)。比較常見的,譬如,加載系統的一些DLL所占用的物理內存,文件共享內存(文件映射),命名共享內存等等。

WS Shared/ Shared WS: WS Shareable的子集,這部分是表示已經和別的進程共享的物理內存。

提交大小/ Private Bytes/ Private: 給當前進程使用而保留的私有虛擬內存的數量,從名字里面的Private可以看出它是專有的,但是和上面的WS Private的區別在於,WS Private是純物理內存,而Private Bytes實際上是虛擬內存的概念,是包含WS Private的,另外一部分是在換頁文件(被從物理內存里面換出去了)里面,有些內存,雖然你提交,但是如果一直沒有使用,也是在頁面文件(換頁文件:PageFile)里面。另外,多說一句,如果要查內存泄漏,可以關注這個值。

Virtrual Size/Size: 當前進程使用的所有的虛擬內存空間,包含共享,非共享,物理,頁面,甚至為程序保留但還未分配的內存。

Committed: Virtual Size減去為程序保留的內存(未分配)。怎么理解為程序保留的但未分配的內存?就是告訴系統我要一塊內存,但暫時還用不上,不過分配的地址得給我,系統就給程序一個不用的地址,但不分配內存,等程序真的要使用時(讀寫),就從頁面或物理內存中分配出來映射到那個地址上。

保留(預定)的內存: 將虛擬內存空間中線性地址0xXXXXXXXX-0xYYYYYYYY標記為預定狀態,但是並沒有分配實際的內存。這樣的好處是我先預定一部分線性地址,以免后面進程空間中沒有這么大的地址范圍可用(一般來講只有服務器上面這樣用得多)。這樣預定后,0xXXXXXXXX-0xYYYYYYYY這塊地址就被占用,地址空間也是資源,雖然還沒有分配任何內存。

提交的內存: 系統從物理內存或者換頁內存分配給進程的那一部分。這部分內存在虛擬內存的線性地址中是連續的,不過在物理內存或者換頁內存中,不一定是連續的。提交但未使用的內存一般都在換頁內存里面,只有去使用的時候,才會換到物理內存里面,這點要注意。

換頁內存: 也屬於已經提交的內存,不過因為不常用,可能被系統置換到磁盤上面以節省物理內存,后面如果要使用會發生換頁錯誤(缺頁中斷),再從磁盤上面置換到物理內存。

缺頁中斷: 當程序要訪問某個地址,系統發現這個地址不在物理內存里,就會產生中斷,然后去讀取頁面文件,把頁面文件中與內存相關的數據拷貝到物理內存,然后標記一下這個地址已經在物理內存中了,然后繼續讓程序運行。

虛擬內存、物理內存和換頁內存: (整個概念還是有一些復雜,這里只簡單描述一下)虛擬內存一般是指整個進程用到的(虛擬)地址空間,之所以是虛擬的,因為中間被系統內存管理器抽象了一層,說到這里就牽涉到一個進程的虛擬內存空間的問題,win32下面一般應用層的虛擬地址空間是2G,然后從虛擬內存地址到物理內存有一個映射關系,這個映射是由內存管理器來完成的,對應用程序透明。而虛擬內存里面一般分成保留內存(壓根就還沒分配的,只是占了地址空間的坑),物理內存(正在使用)和換頁內存(從物理內存換出去的,或者分配后一直未使用),另外物理內存和換頁內存都屬於已經提交的內存。

分頁池: 由內核或驅動程序代表進程分配的可分頁內核內存的數量。可分頁內存是可以寫入其他存儲媒介(例如硬盤)的內存。

非分頁緩沖池: 由內核或驅動程序代表進程分配的不可分頁的內核內存的數量。不可分頁的內存是不能寫入其他存儲媒介的內存。內核在處理低優先級的中斷時,仍可以發生(處理)高優先級的中斷,反過來則不行。缺頁過程也是一個中斷過程(缺頁中斷),那么就遇到了一個問題,即缺頁中斷和其他中斷的優先級的問題。如果在高於缺頁中斷的中斷優先級上再發生缺頁中斷,內核就會崩潰。所以在DISPATCH_LEVEL級別以上,絕對不能使用分頁內存,一旦使用分頁內存,就有發生缺頁中斷的可能,如果發生就會導致內核崩潰(藍屏)。

簡單總結下:

1、工作設置(內存),又叫工作集,即在物理內存中的數據的集合且等於專用工作集與共享工作集的和,Working Set = WS Private + WS Sharable。

2、把所有的"工作集"相加后的值會大於任務管理器中提示的物理內存的使用值,因為工作集包含了共享工作集,這部分數據會重復計算。但是如果你只把專用工作集全部加起來又會發現小於任務管理器中提示的物理內存的使用值,因為你完全沒有計算共享工作集。

3、通俗的講工作設置(內存)是程序占用的物理內存(包含與其他程序共享的一部分),內存專用工作集是程序獨占的物理內存,提交大小(Private Bytes)是程序獨占的內存(包含物理內存和換頁內存)。

4、Committed = VM Private Committed + VM Shareable Committed(VM:虛擬內存)

5、Committed = Working Set + Page File Committed

6、Private Bytes = WS Private + Page File Private

介紹一個測試Windows極限的工具TestLimit,這個玩意功能挺多的,可以探測Windows系統物理內存,虛擬內存,分頁&非分頁內存,進程&線程,句柄,用戶對象和GDI資源等的極限,這里用來探測一下內存的極限。以后有空了可以聊聊Windows其它一些系統資源的極限情況。

命令行 含義 參考PID
TestLimit -r 2048 -c 1 Reserve 2G內存 13520
TestLimit -m 2048 –c 1 Commit 1G 內存, 但不訪問這些內存 12448
TestLimit –d 2048 –c 1 Commit 1G內存, 而且訪問這些內存 13208

*參考了網上的實驗。

根據PID進行對照,會發現,不同的情況影響的內存參數並不一樣,大家可以自己做做這個實驗體會下,對於系統內存機制會有更進一步的了解。

內存優化的概念

1、進行內存優化時,我們主要關注的指標有,工作設置(內存)/Working Set,內存(專用工作集)/WS Private,Private Bytes等幾個,具體實踐時要針對性優化。譬如要優化私有物理內存的使用,那么主要關注當前進程模塊分配內存的特征和大小,找到主要的矛盾點。如果要優化共享內存的使用,除了關注命名共享內存的大小,文件映射之外,還要排除下進程加載的模塊的大小是否有影響。

2、高峰工作集(內存)這個指標一般關注比較小,也較少針對性的優化,主要是評估下內存使用是否平滑。在一些內存資源非常緊張的系統,要注意這個地方,防止內存高峰時,整個系統響應速度雪崩式下降。

3、在進行內存優化時,首先要用相關工具進行內存分配的聚類和分析,然后再制訂優化的方案和計划,首先要分清是內存使用不合理導致的問題,還是某些算法使用內存時可以進行技術上優化,不同的情況消耗的時間是完全不一樣的。

4、補充說明下經常被視為"洪水猛獸"的"刷內存",也就是調用SetProcessWorkingSet和EmptyWorkingSet(實際上是和使用特殊參數調用SetProcessWorkingSet類似)把強制系統把某個進程的部分物理內存置換到換頁內存里面,其實Committed是不會變化的,但是短時間內Working Set會有明顯的變化,為什么說是短時間內,因為雖然某些物理內存頁臨時置換到換頁內存了,但是因為進程馬上可能就用到的,又會立即被換出來,因此做完這個動作之后,關注下該進程的Page Fault值,會發現有明顯的增量,反而可能影響系統性能。這兩點(性能反而下降,假內存優化)也是這種方法被長期詬病的一些原因。不過,任何事情都有兩面性,霸蠻點說,系統為什么提供這種API?完全沒用的話,系統為什么不干掉。其實系統自己也在使用,虛擬內存管理器也會通過這個方法釋放更多的物理內存給應用程序使用。當然,無節操的調用當然不行,什么一秒調用一次這種奇葩的操作,這樣肯定會影響性能,那一般應該怎樣使用呢?這里總結了幾點,大家可以根據情況參考下:

(1) 維持專用工作集(內存)和提交大小(Private Bytes)在一個合適的比例,不停的刷,物理內存600 KB,虛擬內存50M,這一看就不合理,一般來講(個人經驗),維持在1 : 2左右比較合理。實踐中建議根據進程穩定之后的內存來設置這個值。

(2) 建議在程序暫時不被使用的時候(例如最小化,閑時),或者剛剛完成了一件很消耗物理內存的動作之后,進行一次合理的設置。

(3) 啟動2~5分鍾之后進行一次設置,這個跟啟動時內存消耗的特點有關系,很多對象的生命周期都是和進程一樣長,在初始化時,使用了很多STL,ATL或者自定義的對象,消耗了很多內存,但是這些對象可能就啟動時用到了,后面大部分情況可能都用不到,但是它們的生命周期又很長,因此可以在啟動一段時間之后,把這部分內存置換出去。另外,不建議在進程的生命周期中定時的去刷這個內存,即使要刷,也要降低刷的頻率,甚至不刷。

VMMap常用功能舉例

(略,后面有空再補充,這個工具本身就很簡單)。

參考文檔

1、https://www.cnblogs.com/walfud/articles/3256233.html Windows 任務管理器中的幾個內存概念

2、https://www.zhihu.com/question/19858114 Windows 7 里進程管理器里面的各列是什么含義?主要是和內存有關的內存-專用工作集,內存-工作集,內存-提交大小,這些之間有什么區別?

3、https://www.cnblogs.com/awpatp/archive/2012/09/17/2688315.html Windows內存的一些知識點

4、http://shashanzhao.com/archives/832.html windows任務管理器中的工作設置內存,內存專用工作集,提交大小詳解

5、https://superuser.com/questions/185318/process-explorer-not-showing-the-biggest-user-of-my-ram Process Explorer not showing the biggest user of my RAM VMMAP顯示和process explorer不一樣?

6、http://www.cnblogs.com/georgepei/archive/2012/03/07/2383548.html 內存詳解

7、http://www.cnblogs.com/georgepei/archive/2012/03/07/2383445.html 你真的懂任務管理器中有關內存的參數Private(提交大小)和working set(工作設置)嗎?

8、http://blog.csdn.net/lantianjialiang/article/details/5620647 process explorer中的visual size vs working set; private bytes vs WS private

9、http://www.cnblogs.com/awpatp/archive/2010/01/26/1656651.html Task Manager跟Performance Monitor的區別(Working set和Private bytes)

10、https://social.microsoft.com/Forums/zh-CN/155e9b0e-8dd9-449a-960c-ce585850a049?prof=required 為什么任務管理器里面所有進程占用的內存加起來遠遠小於內存使用量?

11、https://blogs.technet.microsoft.com/markrussinovich/2008/11/17/pushing-the-limits-of-windows-virtual-memory/ Pushing the Limits of Windows: Virtual Memory

 

https://blog.csdn.net/magictong/article/details/78998944


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM