谁调整了Windows服务器的内存池大小?
分页内存池与非分页内存池在Windows 服务器上是两个重要的内核资源。系统及其底层的驱动在分配内存时,会从这两个内存池中申请相应的内存,用于存储它们的数据结构。
默认情况下,这两种资源都是在机器启动时,系统在硬件组成的基本上自动计算出来的,也就是说它们的值可能根据内存大小及其它硬件的类型的区别,在不同的机器上有所不同。
从公开的资料中,我们一般可以查询到在Windows操作系统上,Windows 的分页内存池/非分页内存池极限值是:
Region |
IA-64 |
x64 |
x86 |
Process Address Space |
7152 GB |
8192 GB |
2 to 3 GB* |
Paged Pool |
128 GB |
128 GB |
470 to 650 MB |
NonPaged Pool |
128 GB |
128 GB |
256 MB |
所以一般情况下,在32位的系统上,由于分页内存池/非分页内存池的极值都是有限的,且总量并不是很高,如果底层驱动出现内存池泄漏的问题,或是系统总的内存池使用量过高,
就非常容易造成分页内存池/非分页内存池耗尽的情况,从而导致用程序无法正常运行,或是服务失去响应甚至蓝屏的问题。
目前在Windows中,比较常用的查询当前系统的分页内存池/非分页内存池实时使用量的工具是任务管理器。
图1:任务管理器查询实时分页内存池/非分页内存池的使用量
而对于当前系统的分页内存池/非分页内存池的极值大小的查询方法,一般是使用process explorer工具(需要网络支持)。
使用方法为:
1: 用默认路径安装Windbg工具:
https://msdn.microsoft.com/en-us/windows/hardware/gg463016.aspx。
2:下载Process
Explorer工具:
https://technet.microsoft.com/en-us/sysinternals/bb896653.aspx。
3: 运行Process
Explorer,在Options -> Configure Symbols… 中配置符号,如下图2(注: 这里需要服务器可连接到微软的符号服务器以自动下载符号)。
图2: Process Explorer配置符号
4: 然后在Process Explorer菜单中,选择view -> System Information… 来查看当前的分页内存池/非分页内存池的极值。
这里以一台Windows 2003 sp2 x86的服务器为例:
在上面示例的系统上,我们可以看到当前服务器在2GB物理内存的情况下,分页内存池极限值为362,496KB,约354MB,而非分页内存池的极值是262,140KB,约256MB。
比较上述极值与我们之前查询到的理论值,我们可以看到,非分页内存池的大小(256MB)与资料中查到的极限值基本一致,但是分页内存池的值354MB要远小于理论上的470
- 650MB。这是为什么呢?
这个主要是因为在Windows 2003安装完成后,系统中并没有把paged pool设置到可以支持的最大值,而是有一定的保留。我们可以根据KB312362(https://support.microsoft.com/?id=312362),手动的调整下面的注册表值,把分页内存池的极值上调到当前机器可支持的最大值
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session
Manager\Memory Management\PagedPoolSize
= 0xFFFFFFFF.
上述注册表值默认是0,表示让系统自动设定。如果把它设置成0xffffffff,就可以把当前机器的paged
pool 的极值,调整到机器真正支持的最大值了。
同样是前面我们测试的服务器,在做了相应调整后,我们可以看到它的分页内存池的最大值被调整到了530MB左右:
图4:Windows 2003 SP2 x86调整PagedPoolSize后的分页内存池大小
这里我们看到530MB已经是这台服务器的极值了。如果这台机器的物理内存进行调整,分页内存池的最大值也可能随之有一定的增减。
对于非分页内存池的极大值,系统默认已经是使用到了所支持的最大值,它是不能通过注册表的设置来提高它的极大值的。
从操作系统的层面,除去调整上述的注册表值PagedPoolSize做手动的指定,还会有两种情况会影响到系统的分页内存池/非分页内存池的大小:
1:系统运行在/3GB的模式。
2:系统安装了终端服务器的角色。
这边我们看一下这两种情况下,系统的内存池的极值有什么变化:
1:在开启/3GB的模式(即在boot.ini中增加了/3GB)时,系统的内核地址寻址空间从2GB下降到1GB,这样的话系统的内存池的极值也下调了,而且幅度比较大。
在同一台Windows 2003 SP2 x86服务器上,我们可以看到增加/3GB后,系统的分页内存池/非分页内存池的极值降低了很多:
图5:Windows 2003 SP2 x86开启/3GB后的分页内存池/非分页内存池大小
在/3GB的模式下,我们看到分页内存池极值调整为196,608KB,约192MB,而分页内存池的大小下降为129,276KB,约126MB。
2:在安装了终端服务器的角色后,系统的分页内存池也会有一定下降:
图6:Windows 2003 SP2 x86终端服务器的分页内存池/非分页内存池大小
可以看到系统的分页内存池下降到了256,000KB,约250MB,而非分页内存池没有变化。
上述两种情况都是从操作系统的角度,对内存池的大小进行调整。
除去上述两种情况,其实在硬件层面上,我们还有另一个选项,会影响到系统的分页内存池极值大小,这个选项就是内存热插拔功能(hot-add memory)。
在Windows 2003 x86的企业版本/数据中心版本中,操作系统本身提供对内存热插拔的支持,即在不关机的情况下,可以动态的支持新增的内存,这样可以避免机器的维护时间及停机周期。但是相应的,服务器也需要在硬件层面上支持内存热插拔的功能。此项功能只会在硬件支持内存热插拔时,才会对系统的分页内存池有影响。在有一些虚拟机上,由于它们也提供发对服务器内存热插拔功能的支持,所以这些虚拟服务器也可能会碰到相似的问题。
具体情况为:
在硬件/系统都支持内存热插拔功能的前提下,为了实现对热插内存的支持,系统需要事先在开机时,就分配出一部分内核资源,用于提供对可能新增加的内存的支持。也就是说这部分事先分配的资源并不是依赖于当前硬件配置,而是依赖于服务器可以支持到的最大内存容量。在32位系统上,系统最大可支持的内存是64GB,所以内存热插拔最大可以预留对64GB热插拔内存的支持。而这部分资源的分配,就会影响到系统总的分页内存池大小。
通过之前的测试,我们知道一台Windows 2003 sp2 x86的终端服务器系统上,如果4GB物理内存,且不支持内存热插拔时,分页内存池应该是略大于250MB(如图6),大概在260MB左右。
当这台机器提供64GB的热插拔内存支持时,系统的分页内存池会下降大约80MB左右,从DUMP文件中我们可以很清楚的看到这一点。下面这部分数据来自一台Windows 2003 sp2 x86 4GB物理内存的企业版本终端服务器的DUMP文件。
1:
kd> !vm
***
Virtual Memory Usage ***
Physical Memory: 1048347 ( 4193388 Kb)
…
NonPagedPool Usage: 26116 ( 104464 Kb)
NonPagedPool Max: 65536 ( 262144 Kb) < ------ 非分页内存池大小没有变化
PagedPool 0 Usage: 5141 ( 20564 Kb)
PagedPool 1 Usage: 9470 ( 37880 Kb)
PagedPool 2 Usage: 9484 ( 37936 Kb)
PagedPool 3 Usage: 9483 ( 37932 Kb)
PagedPool 4 Usage: 9430 ( 37720 Kb)
PagedPool Usage: 43008 ( 172032 Kb)
PagedPool Maximum: 43008 ( 172032 Kb) < ----- 分页内存池已经比不提供内存热插拔时的250MB低了约82MB,目前只有168MB。
内存热插拔可以提供更灵活的内存管理机制,但是也会同时影响到服务器的分页内存池极值,造成分页内存池更容易被耗尽,而引起各种异常。
从系统的角度,我们在注册表中提供了一个接口,用于指定系统可以支持的热插拔内存大小:
Path |
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management |
Value |
DynamicMemory |
Type |
REG_DWORD |
Data |
0x1 |
这个值指定了系统可以支持多少GB的热插拔内存。由于系统内存大都超过1G,设置成1就表示系统已经基本禁用了Hot-add Memory的功能。这样就可以避免系统分页内存池在开机时大幅降低的问题。当然,我们也可以考虑直接把热插拔内存的功能从硬件的层面禁用掉。虚拟机控制平台也可能有相应的选项来禁用热插拔内存的功能。上述4GB内存的服务器在硬件层面上禁用掉热插拔内存功能后,系统的内存池的变化为:
kd> !vm
*** Virtual Memory Usage ***
Physical Memory: 1048375 ( 4193500 Kb)
…
NonPagedPool Usage: 12526 ( 50104 Kb)
NonPagedPool Max: 65279 ( 261116 Kb)
PagedPool0 Usage: 26806 ( 107224 Kb)
PagedPool1 Usage: 5100 ( 20400 Kb)
PagedPool2 Usage: 5125 ( 20500 Kb)
PagedPool3 Usage: 5128 ( 20512 Kb)
PagedPool4 Usage: 5103 ( 20412 Kb)
PagedPool Usage: 47262 ( 189048 Kb)
PagedPool Maximum: 66560 ( 266240 Kb) < ----分页内存池已经调整回260MB
这样就可以避免由于热插拔内存功能预留大量内核资源,导致分页内存池大量下降的问题了。
综上所述,我们知道除去系统本身的硬件配置外,还有四个设定可能会影响到分页内存池/非分页内存池的极值大小:
1: 手动的设定PagedPoolSize注册表值,可以影响分页内存池的大小。
2: 使用/3GB的模式,会影响分页内存池/非分页内存池的大小。
3: 使用终端服务器模式,会影响到分页内存池/非分页内存池的大小。
4: 使用内存热插拔的功能支持大的热插拔内存时,会影响到分页内存池的大小。
希望这些介绍,对于我们在调试服务器分页内存池/非分页内存池的问题时,能有所帮助。
微软企业平台支持部
刘圣
本博文仅供参考,微软公司对其内容不作任何责任担保或权利赋予。