A Windows operating systems divides memory in two spaces: user-mode and kernel-mode. By default 2GB is assigned to kernel mode (1GB if the /3GB switch is used, which is not the case). The user-mode memory is for regular application usage, the kernel-mode memory is for “special” purposes.
Part of the kernel memory are two pools:
- Non-paged memory pool: Objects in this pool are never paged
- Paged memory pool: Objects in this pool can be paged
The size of these pools is limited and could become critical. Especially in a multi-user environment like, remote desktop shared service (RDSH), with an x86 processor architecture the paged memory pool limit can be reached sooner than you might expect.
Limits
The memory limits are specified on the page MSDN – Memory Limits for Windows Releases. On this page you will read that for an x86 operating system the paged pool limit for Windows Server 2003 is 530MB and for the nonpaged pool the limit is 256MB (or 128MB with 4GT).
Now what you probably didn’t knew is that a default configured servers have a maximum pool size that is (a lot) smaller than the limits mentioned in the article.
Finding the actual limit
The actual limit of the (non)paged, the maximum size, cannot be read from the Task Manager. This can be done with either Sysinterals Proces Explorer or the Windows Symbolic GUI Debugger (WinDbg). In this example I’m using WinDbg since this is the most powerful tool. To view the (non)paged limit in Process Explorer you need to specify the symbol search path. This is explained in article CTX129384.
The !vm extension displays summary information about virtual memory use statistics on the target system. If we run this on a Windows Server 2003 SP2 x86 machine we get the following results:
Memory limit theoretical |
Actual limit | Difference | |
Nonpaged pool |
256MB |
255MB |
1MB |
Paged pool |
530MB |
178MB |
352MB |
So where the actual nonpaged pool limit is near the limit Microsoft stated (1MB difference) the paged pool limit is not even close to the theoretical limit (a difference of 352MB).
So what happened?
The maximum size of the pool is calculated by the system during boot. The result of this calculation, based on the physical memory, is an optimal value for most systems. This implies that there are exceptions, one of them are remote desktop shared hosting-servers (RDSH, the services formerly know as terminal servers).
Changing the (non)paged pool memory size
By default the maximum size is determined by the system, but the actual limit (the maximum size of the memory pool) can be configured in the registry. No disclaimer here, just be careful okay?
The (non)paged memory pools are handled by the Session Manager (specifically by Memory Management), therefor the limits (etc.) are configured in the registry key :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
Paged memory pool
- Value: PagedPoolSize
- Type: REG_DWORD
- Value
Value Description 0x00000000 The system calculates an optimal value number of bytes Creates a paged pool of the specified size 0xFFFFFFFF The system calculates the maximum paged pool allowed for the system in this configuration. - More information : technet
Warning: If you increase the paged memory pool the number of free page table entries (PTEs) will decrease. Always create a baseline of the required and number of free PTEs before – and – after the change.
Nonpaged memory pool
- Value: NonPagedPoolSize
- Type: REG_DWORD
- Value
Value Description 0x00000000 The system calculates an optimal value number of bytes Creates a nonpaged pool of the specified size - More information : technet