Thoughts from the EPS Windows Server Performance Team
Good morning AskPerf! We’ve had plenty of discussions in the past about Pool Memory – both Paged and NonPaged. Today we’re going to review how we can determine the Pool Memory usage from a memory dump file via the !poolused command. A quick note – if you’re trying to identify a leaking pool tag, analyzing it from a post-mortem dump won’t show you any trends – only the usage as a point in time snapshot. With that, let’s begin as we usually do – looking at the parameters for the command:
If you run the !poolused command with no flags, you will see summary information, sorted by pool tag – as you can see by our first example below. We’re using a dump file today from the same machine that we used to capture data for our post on !vm and !memusage. Remember that you may need to use the GFLAGS utility to enable Pool tagging if it isn’t already enabled.
1: kd> !poolused Sorting by Tag Pool Used: NonPaged Paged Tag Allocs Used Allocs Used 8042 4 3944 0 0 PS/2 kb and mouse , Binary: i8042prt.sys AcdN 2 1072 0 0 TDI AcdObjectInfoG AcpA 3 192 1 504 ACPI arbiter data , Binary: acpi.sys AcpB 0 0 4 704 ACPI buffer data , Binary: acpi.sys AcpD 44 14720 0 0 ACPI device data , Binary: acpi.sys AcpF 9 360 0 0 ACPI interface data , Binary: acpi.sys AcpM 0 0 1 128 ACPI miscellaneous data , Binary: acpi.sys AcpO 4 208 0 0 ACPI object data , Binary: acpi.sys AcpP 4 352 0 0 ACPI power data , Binary: acpi.sys AcpR 3 1616 9 4208 ACPI resource data , Binary: acpi.sys AcpS 51 1288 17 704 ACPI string data , Binary: acpi.sys Acpg 1 88 0 0 ACPI GPE data , Binary: acpi.sys Acpi 1 136 0 0 ACPI generic data , Binary: acpi.sys Acpt 1 120 0 0 ACPI table data , Binary: acpi.sys
There’s lots of information here to be sure, but it doesn’t really help up identify the top pool memory consumers – so now let’s try the 0x2 and 0x4 flags. Remember that these are mutually exclusive ...
1: kd> !poolused 2 Sorting by NonPaged Pool Consumed Pool Used: NonPaged Paged Tag Allocs Used Allocs Used INOF 37 2744896 0 0 UNKNOWN pooltag 'INOF', please update pooltag.txt R300 42 1360664 85 4609640 ATI video driver MmCm 23 1090080 0 0 Calls made to MmAllocateContiguousMemory , Binary: nt!mm Wmit 51 761856 13 51448 Wmi Trace IpFI 1940 608560 0 0 filter blocks , Binary: ipsec.sys File 3148 479792 0 0 File objects Devi 278 470856 0 0 Device objects Thre 475 300200 0 0 Thread objects , Binary: nt!ps WmiG 1276 275616 0 0 Allocation of WMIGUID FMsl 1300 270400 0 0 STREAM_LIST_CTRL structure , Binary: fltmgr.sys Mm 13 222432 4 2384 general Mm Allocations , Binary: nt!mm Ntfr 3111 199560 0 0 ERESOURCE , Binary: ntfs.sys Ntf0 3 196608 1720 49424 general pool allocation , Binary: ntfs.sys
First our NonPaged Pool used, and now here is our Paged Pool usage:
1: kd> !poolused 4 Sorting by Paged Pool Consumed Pool Used: NonPaged Paged Tag Allocs Used Allocs Used MmSt 0 0 2878 9996560 Mm section object prototype ptes , Binary: nt!mm R300 42 1360664 85 4609640 ATI video driver Gh05 0 0 249 2208720 GDITAG_HMGR_SPRITE_TYPE , Binary: win32k.sys CM35 0 0 126 2064384 Internal Configuration manager allocations , Binary: nt!cm Ntff 5 1040 1314 1093248 FCB_DATA , Binary: ntfs.sys NtfF 0 0 432 407808 FCB_INDEX , Binary: ntfs.sys Ttfd 0 0 575 395128 TrueType Font driver IoNm 0 0 2314 310504 Io parsing names , Binary: nt!io CM25 0 0 17 278528 Internal Configuration manager allocations , Binary: nt!cm Obtb 0 0 95 244544 object tables via EX handle.c , Binary: nt!ob
To refine your results further, you can append the /t parameter to return only the top n rows. As an example, if you ran !poolused /t 10 4 you would get the top ten tags in terms of Paged Pool usage.
For those tags where there is no entry in the pooltag.txt file, you can use the findstr command that we showed you in our post, An Introduction to Pool Tags. OK, there’s one last tip. If you want to filter down the list even further, you can append the TagString parameter to your command as shown below. The second parameter is case-sensitive. Here’s an example of filtering on NonPaged Pool for tags beginning with TCP:
1: kd> !poolused 2 TCP* Sorting by NonPaged Pool Consumed Pool Used: NonPaged Paged Tag Allocs Used Allocs Used TCPt 25 99616 0 0 TCP/IP network protocol , Binary: TCP TCPC 350 30120 0 0 TCP connection pool , Binary: TCP TCPc 436 20928 0 0 TCP/IP network protocol , Binary: TCP TCPA 51 18768 0 0 TCP/IP network protocol , Binary: TCP TCPB 13 18392 0 0 TCP/IP network protocol , Binary: TCP TCPT 11 4408 0 0 TCB pool , Binary: TCP TCPr 9 824 0 0 TCP request pool , Binary: TCP TCPY 1 248 0 0 SYN-TCB pool , Binary: TCP TCPa 5 160 0 0 TCP/IP network protocol , Binary: TCP TCPi 1 40 0 0 TCP/IP network protocol , Binary: TCP TOTAL 902 193504 0 0
That’s it for this post. A quick post, but this is definitely one of those commands that’s handy to have available! Until next time …
Additional Resources:
- CC Hameed
Sorry for being thick but which tool are you using to run the !poolused command from?
The tool we are using in all of the Debug101 posts are the Debugging Tools for Windows, Windbg.exe specifically. You can download them from Microsoft.com by querying on 'debugging tools for Windows'.
Hi, thanks for the great post.
#1 I am wondering could you please provide a practical example of how can we utilize info provided !poolused during debugging?
#2 why "allocs" always a lot smaller than "Used"?
thank you for your time and help.
Hi, is the Used field in bytes, or kilobytes?