谁调整了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: 使用内存热插拔的功能支持大的热插拔内存时,会影响到分页内存池的大小。

希望这些介绍,对于我们在调试服务器分页内存池/非分页内存池的问题时,能有所帮助。

                                                                                                    微软企业平台支持部

                                                                                                                            刘圣

 

本博文仅供参考,微软公司对其内容不作任何责任担保或权利赋予。