poolmon.exe displays data that the Windows operating system collects about memory allocation from the system's paged and nonpaged kernel pools, as well as the memory pools used for Terminal Services sessions. The data is grouped by pool allocation tag. This information can be used by Microsoft Technical Support to find kernel mode memory leaks.
A memory leak is caused by an application or by a process that allocates memory for use but that does not free the memory when the application or process finishes. Therefore, available memory is completely used over time. Frequently, this condition causes the system to stop functioning correctly.
In regards to Mobility, this usually manifests as unusually high "paged memory" or "nonpaged memory" values on the server status screen in the Mobility Console. Clients may also be unable to connect to the Mobility server, receiving the error "The client session was terminated due to lack of resources on the Mobility server."
On the Windows Server CD, poolmon.exe is in the Support.CAB file. Support.CAB is located under the \Support\Tools folder. poolmon.exe can also be downloaded from Microsoft as part of the Windows Driver Kit here.
For 32-bit versions of Windows, use poolmon -c to create a local tag file that lists each tag value assigned by drivers on the local machine (%SystemRoot%\System32\Drivers\*.sys). The default name of this file is Localtag.txt.
You can use the poolmon -g parameter to display the names of Windows components and commonly used drivers that assign each pool tag. If you find a problem in allocations with a particular tag, this feature helps you identify the offending component or driver.
The components and drivers are listed in the Mapped_Driver column, the right-most column in the display. The data for the Mapped_Driver column comes from pooltag.txt, a file installed with PoolMon.
To detect a memory leak
- Start PoolMon with the parameters -p -p (display only allocations from the paged pool) and -b (sort by the number of bytes): poolmon -p -p -b
- Let PoolMon run for a few hours. Because starting PoolMon changes the data, it must regain a steady state before the data is reliable.
- Save the information generated by PoolMon, either as a screenshot, or by copying it from the command window and pasting it into Notepad.
- Returning to PoolMon, press the p key twice to display only allocations from the nonpaged pool.
- Repeat steps 3 and 4 approximately every half-hour for at least two hours, switching between the paged and nonpaged pool displays each time.
- When data collection is complete, examine the Diff (allocation operations minus free operations) and Bytes (number of bytes allocated minus number of bytes freed) values for each tag, and note any that continually increase.
- Next, stop PoolMon, wait for a few hours, and then restart PoolMon.
- Examine the allocations that were increasing, and determine whether the bytes are now freed. The likely cause is allocations that have still not been freed or have continued to increase in size.
Examine a Pool Memory Leak
The following example demonstrates using PoolMon to investigate a pool memory leak from a suspected printer driver.
In this example, PoolMon displays data that Windows collects about memory allocations with the Dsrd tag.
Printer drivers assign the Drsd tag when they allocate Graphical Device Interface (GDI) objects and associated memory.
If a printer driver has an object leak, the memory allocated with the Drsd tag also will leak.
Note: Before running the steps in this example, ensure that the printer you are using will not be interrupted until you are finished. Otherwise, the results may be invalid.
At the command line, type the following:
This command directs PoolMon to display information for allocations with the Drsd tag. (Pool tags are case-sensitive, so be sure to type the command exactly as shown.)
Record the values in the Diff and Bytes columns. In the following sample display, the value of Diff is 21 and the number of Bytes is 17472.
Memory: 130480K Avail: 91856K PageFlts: 1220 InRam Krnl: 2484K P: 7988K
Commit: 30104K Limit: 248432K Peak: 34028K Pool N: 2224K P: 8004K
Tag Type Allocs Frees Diff Bytes Per Alloc
Drsd Paged 560 ( 177) 539 ( 171) 21 17472 ( 4992) 832
Send a job to the printer, wait briefly for Windows to return to normal, and then record the values for the Diff and Bytes columns.
Memory: 130480K Avail: 91808K PageFlts: 1240 InRam Krnl: 2488K P: 7996K
Commit: 30152K Limit: 248432K Peak: 34052K Pool N: 2224K P: 8012K
Tag Type Allocs Frees Diff Bytes Per Alloc
Drsd Paged 737 ( 0) 710 ( 0) 27 22464 ( 0) 832
When the memory management for the printer driver is working properly, the value of Diff should return to its original value of 21 after printing. However, as the preceding output illustrates, the value of Diff rose to 27, and the number of Bytes rose to 22464. The difference between the initial and subsequent output means that six Drsd blocks, with a total of 4992 bytes, leaked during printing.
To find specific .sys files by PoolMon tag, on the machine where PoolMon was run, go to the %windir%\system32\drivers folder and run: findstr /I /m /l *.sys
Example: findstr /I /m /l TwEg *.sys
This will dump out any files that have this tag (TwEg) in them to help track down the culprit.
If no files are returned, it may be necessary to do this in a different folder on a machine which has .sys files. It may be beneficial to list all of the .sys files on the machine in order to run the findstr command in order to find what is allocating 'TwEg'. This may be Windows itself. If that is the case, then a winmsd dump may help the troubleshooting process from there.