Lots of times you have a memory dump and need to get some information about the virtual and physical memory state. How much pool is in use? How much physical memory is in use? What about the system working set?
Turns out that there’s no one command that will tell you absolutely everything, you’ll need to bring together the output of several commands in order to get a clear picture of what’s going on.
!vm
Whenever I suspect I’m dealing with a system that is low on virtual memory, my go to command is !vm. This gives you an overview of the current page file usage, available physical pages, free system PTEs, the pools, process memory usage, etc:
What’s also nice is that !vm knows about the failed allocation counters in the system, so, for example, if there have been any failed pool allocations !vm will let you know.
!sysptes
System PTEs are a popular resource in the system. They’re used for all kinds of things, a common one being kernel stacks. Also, a common question I get is, “why is MmGetSystemAddressForMdlSafe failing?” The most common answer is a lack of system PTEs, which we see in the !vm output but we can get a better picture of with !sysptes:
We can see here the largest free block, which is going to indicate the largest free contiguous system PTE range there is in the system. This lets us know what the largest MDL we could current map with MmGetSystemAddressForMdlSafe is.
!memusage
!vm also gave us some info about physical memory in the system, but we can get a finer grained view with another command.
In Windows, the physical address space is broken up into PAGE_SIZE chunks. Each page is referenced by an index, which is called a page frame number (PFN). So, f you have a PFN, you can find the physical address by multiplying the PFN by PAGE_SIZE (4K on x86/x64, 8K on IA64).
All of the PFNs in the system are collectively referred to as the page frame database (PFD). Each page in the page frame database has a particular state associated with it. Aside from two of the states (active and transition), pages in the same state are linked together in a linked list. We can see the state of the pages in the PFD via the !memusage 8 command (!memusage with other flags provides even more information):
nt!MmSystemCacheWs
Finally, we can investigate the system working set, which is the memory in use from the file system cache, paged pool, and pageable driver/kernel sections. This one is a bit trickier to track down as it is a kernel data structure that we must explore with the dt command. First, we’ll find the address of nt!MmSystemCacheWs:
Note the lack of type information here, which is standard for public PDBs such as the ones shipped for Microsoft components. Bummer, but some Googling lets us know that the data type of this structure is MMSUPPORT. Thus, we can inspect the structure and its fields:
The WorkingSetSize field is the interesting one for our discussion. This indicates the number of pages taken up by the system working set. On my x86 system this is (0×68fb * 4K), which is about 110MB.




!vm has some additional flags that can be useful when troubleshooting memory allocation failures. For example, 32-bit Vista and Win7 support !vm 0×21 which dumps statistics about kernel space VA usage. This is useful for example when you get a pool allocation failure yet the system seems to have plenty of available commit and physical memory.
Another win7 change is that MmSystemCacheWs is now split into 3 separate working sets: MmSystemCacheWs, MmPagedPoolWs and MmSystemPtesWs.
Thanks for the added info Pavel!
Interesting that they’ve broken the working sets out, definitely makes more sense.
We’re running Win7 for our everyday use computer at home, I’ll have to check out the !vm improvements and the new working set breakdown.