平台人生
作者平台人生·2017-10-13 14:53
软件开发工程师·平台人生

Windows 内存管理的那点事

字数 3026阅读 5601评论 1赞 2

说到Windows的内存管理,你可能会想到虚拟内存、物理内存、Pool paged、Pool non-paged等等。那么他们究竟都是什么?他们之间又有着哪些千丝万缕的关系呢?下面咱们就一一来说道说道。

首先说物理内存,显而易见,物理内存就是我们所说的RAM,它真实存在着,Windows在使用物理内存时,会通过可寻址内存的最小单元来分配和使用,这个最小单元就是内存页/Page。对于32-bit和64-bit的Windows来说page的大小都是4KB,而IA64版本的Windows Server中page大小为8KB。

同时为了避免物理内存耗尽,Windows还有个page file,它是在物理磁盘上的一个特殊文件,用来模拟物理内存,当物理内存紧张时它就会派上用场,这会产生一个动作,叫做Paging,就是将物理内存中的内容转移到硬盘的过程。那么对于Windows来说,它的实际交付内存的极限就是物理内存加上Page file。那么问题来了,我的Page file是多大?正如前面所说Page file是磁盘用于模拟物理内存的特殊文件,这个文件实际是我们可以进行设置的,你可以定义使用哪块物理磁盘的空间,也可以定义多个Page file,当然也可以定义它的大小。不过需要注意一点,Page file的大小需要考虑满足内存转储的需求,内存转储时会将内存中的内容记录到Page file中,如果Page file设置过小会造成转储失败或不完全。

通常来说要满足下表中的最小需求:

转储类型Page file大小
完全内存转储RAM+100M
核心内存转储物理内存 Page file最小尺寸
< 128 MB > 50 MB
< 4 GB > 200 MB
< 8 GB > 400 MB
>= 8 GB > 800 MB
最小内存转储>2MB 且位于引导卷

另外需要注意一点是,在Windows Server2008及以后的版本中,Page file是可以动态管理的,最小为1倍RAM和1GB中较大值,最大为3倍RAM和4GB中较大值,所以在2008以后的版本中你会发现你的磁盘空间莫名奇妙的不见了,不要慌张这很可能是Page file占用了。查看分类的Page file及调整Page file可以在高级系统设置中配置:

微信图片_20171013144821.jpg

微信图片_20171013144821.jpg

「Page file」如何查看当前是否使用Page file呢?可以在任务管理器的性能页面中查看,正如前面所说可交付内存为物理内存与Page file的总和,那么当实际提交内存大于物理内存的总量时,就说明使用到了Page file啦。

微信图片_20171013144855.jpg

微信图片_20171013144855.jpg

如果实际交付内存量持续增长接近可交付内存的极限,那么就说明内存资源十分紧张,这时候如果想知道究竟是哪个坏家伙占用了大量内存,我们又应该关注什么呢?这时就需要关注进程的工作集和进程使用的交付内存量。工作集是一个进程正在使用的物理内存量,可以通过性能监视器中的\Process()\working Set计数器中找到消耗内存最多的进程,而进程占用的交付内存量则需通过\Process()\Private Bytes计数器来查看,这部分是进程私有的,也是判断进程内存泄漏最好的计数器。

上面所述均是与物理内存相关的内容,它们存在于一个真实的世界,这部分是由内核来掌握的。而对于一个进程来说,它们都运行在各自的虚拟世界中,这就出现了虚拟内存。虚拟内存对于进程而言是私有的,它可以很大,但内核可以只提供它实际需要的很小的一部分可交付内存,与应用进程类似,内核也活在一个虚拟空间中,但内核模式的虚拟内存则是所有进程共享的。对于32-bit系统而言,最大寻址空间为4GB,而进程的可以使用的虚拟地址空间最大为2GB,剩余2GB为内核使用;对于64-bit系统而言,最大寻址空间为16TB,同样进程和内核各自可使用8TB。

虚拟内存

对于应用进程来说,32-bit系统下2GB的虚拟地址略微显得有些局促,往往有些进程会自私的想要声明占用更多的虚拟内存,/3GB开关实现了这一需求。通过/3GB开关可以使应用进程的内存地址空间扩大到3GB,而内核模式的内存地址降低到1GB,效果是这样的:

微信图片_20171013145012.jpg

微信图片_20171013145012.jpg

对于内核模式来说,虚拟内存又分为Pool paged、Pool non-paged、PTEs。他们又都是什么呢?来看下表:

Pool paged系统空间的虚拟内存区域,为特定系统进程试用,该区域数据可被Page in和Page out
Pool non-paged包含系统虚拟内存地址的内存池,必须保证常驻物理内存
System Page Tabe Entries(PTEs)用于把虚拟内存映射到物理内存的内存结构

他们在内存中又是如何分配的呢?我们以32-bit系统为例来看下,如下图,他们每一部分都占据了内核模式虚拟内存的固定空间,当其中的Pool paged耗尽时就会造成系统的崩溃。

微信图片_20171013145142.jpg

微信图片_20171013145142.jpg

为了缓解这一情况,在32bit的Windows Server 2008中采用的是动态核心虚拟内存设置,Pool paged、Pool non-paged、PTEs等各部分不再固定大小,而是集中在一个池中,任何一个资源都可以使用其他资源持有过得内存,如下图:

微信图片_20171013145206.jpg

微信图片_20171013145206.jpg

这就降低了因某一部分内核资源耗尽而导致系统崩溃的概率,然而内核可用的虚拟内存总计只有2GB,如果某一个驱动程序代码写的不够严谨,还是很容易造成核心内存耗尽,那我们该如何是好呢?答案是升级为64-bit操作系统,8TB的核心内存耗尽的可能性就大大降低了。

Pool paged、Pool non-paged、PTEs的使用情况可以通过\Memory\Pool Paged Bytes、\Memory\Pool Nonpaged Bytes和\Memory\Free System Page Table Entries三个计数器来监测,\Memory\Pool Paged Bytes是当前Pool paged的尺寸,\Memory\Pool Nonpaged Bytes是当前Pool non-paged的尺寸,而\Memory\Free System Page Table Entries则是当前系统中PTE的可用条目,通过性能监视器中这三个计数器我们可以进一步关注核心内存资源的使用情况,但是很遗憾,Pool paged和Pool non-paged的最大尺寸我们是无法通过性能监视器获取到的。

另外需要注意一点的是/3GB开关的启用对于核心内存是非常不利的,虽然应用进程的可用虚拟内存增大了,但内核模式的虚拟内存减少会使Pool paged、Pool non-paged、PTEs的容量剧烈下降,特别是对于物理内存较大的系统而言,Page Frame Number(PFN)数据库管理着RAM页面,它会随RAM的增大而增大,这将进一步压缩Pool paged、Pool non-paged、PTEs的空间。而当PTE匮乏时系统将被挂起,所以说/3GB开关的启用对于系统运行往往是利大于弊。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

2

添加新评论1 条评论

wuwenpinwuwenpin软件开发工程师南京
2017-10-14 17:07
学习了、
Ctrl+Enter 发表

本文隶属于专栏

作者其他文章

相关文章

相关问题

相关资料

X社区推广