内存⼯作设置(⼯作集)、提交⼤⼩概念简述
内存⼯作设置(⼯作集)、提交⼤⼩概念简述
前⾔
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、把所有的"⼯作集"相加后的值会⼤于任务管理器中提⽰的物理内存的使⽤值,因为⼯作集包含了共享⼯作集,这部分数据会重复计算。但是如果你只把专⽤⼯作集全部加起来⼜会发现⼩于任务管理器中提⽰的物理内存的使⽤值,因为你完全没有计算共享⼯作集。
安卓2.3升级4.03、通俗的讲⼯作设置(内存)是程序占⽤的物理内存(包含与其他程序共享的⼀部分),内存专⽤⼯作集是程序独占的物理内存,提交⼤⼩(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 1Reserve 2G内存13520
TestLimit -m 2048 –c 1Commit 1G 内存, 但不访问这些内存12448
TestLimit –d 2048 –c 1Commit 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、 Windows 任务管理器中的⼏个内存概念
2、 Windows 7 ⾥进程管理器⾥⾯的各列是什么含义?主要是和内存有关的内存-专⽤⼯作集,内存-⼯作集,内存-提交⼤⼩,这些之间有什么区别?
3、 Windows内存的⼀些知识点
4、 windows任务管理器中的⼯作设置内存,内存专⽤⼯作集,提交⼤⼩详解
5、 Process Explorer not showing the biggest user of my RAM VMMAP显⽰和process explorer不⼀样?
6、 内存详解
阳澄湖在哪里7、 你真的懂任务管理器中有关内存的参数Private(提交⼤⼩)和working set(⼯作设置)吗?
8、 process explorer中的visual size vs working set; private bytes vs WS private
9、 Task Manager跟Performance Monitor的区别(Working set和Private bytes)
10、 为什么任务管理器⾥⾯所有进程占⽤的内存加起来远远⼩于内存使⽤量?
11、 Pushing the Limits of Windows: Virtual Memory
发布评论