Debug 101: Examining Memory Use

Debug 101: Examining Memory Use

  • Comments 1
  • Likes

Happy Friday AskPerf!  No alphabet soup or Sesame Street quips today.  Today, we’re going to take a quick look at two debugger commands that you can use to examine memory use, !vm and !memusage.  Why two commands?  One shows you information about virtual memory usage (!vm) and the other one displays information about physical memory use (!memusage).  Let’s take a look at each one, beginning with the parameters for !vm:

Each of the parameters define a different subset of information that is displayed in the output.  !vm takes a single parameter, which is a number representing the desired option flags.  Each flag can be enabled by setting a specific bit.  This allows fine granularity of the return data.  When you add the desired bits together, you get a bitmask that contains only the specific information that you want returned.  The default is 0, which displays system-wide virtual memory info and the memory info for each process.

Flag Function
Bit 0 (0x1) Omit process-specific statistics
Bit 1 (0x2) Include Memory Management thread stacks
Bit 2 (0x4) Include Terminal Server Memory Usage (Windows XP and later)
Bit 3 (0x8) Include the Page File Write Log (Windows XP and later)
Bit 4 (0x10) Include Working Set Owner thread stacks (Windows XP and later)
Bit 5 (0x20) Include Kernel Virtual Address usage (Windows XP and later)

Let’s take a look at what the output from these commands looks like.  For this post, I dumped a 32-bit Windows XP machine using the trusty CrashOnCtrlScroll method, beginning with a simple !vm command:

1: kd> !vm

*** Virtual Memory Usage ***
Physical Memory: 523793 ( 2095172 Kb)
Page File: \??\C:\pagefile.sys
Current: 2095104 Kb Free Space: 2031992 Kb
Minimum: 2095104 Kb Maximum: 4190208 Kb
Available Pages: 389780 ( 1559120 Kb)
ResAvail Pages: 436684 ( 1746736 Kb)
Locked IO Pages: 54 ( 216 Kb)
Free System PTEs: 149380 ( 597520 Kb)
Free NP PTEs: 32766 ( 131064 Kb)
Free Special NP: 0 ( 0 Kb)
Modified Pages: 754 ( 3016 Kb)
Modified PF Pages: 753 ( 3012 Kb)
NonPagedPool Usage: 3230 ( 12920 Kb)
NonPagedPool Max: 65536 ( 262144 Kb)
PagedPool 0 Usage: 3862 ( 15448 Kb)
PagedPool 1 Usage: 458 ( 1832 Kb)
PagedPool 2 Usage: 445 ( 1780 Kb)
PagedPool 3 Usage: 471 ( 1884 Kb)
PagedPool 4 Usage: 460 ( 1840 Kb)
PagedPool Usage: 5696 ( 22784 Kb)
PagedPool Maximum: 92160 ( 368640 Kb)
Session Commit: 1603 ( 6412 Kb)
Shared Commit: 6500 ( 26000 Kb)
Special Pool: 0 ( 0 Kb)
Shared Process: 2908 ( 11632 Kb)
PagedPool Commit: 5696 ( 22784 Kb)
Driver Commit: 2235 ( 8940 Kb)
Committed pages: 104454 ( 417816 Kb)
Commit limit: 1008403 ( 4033612 Kb)

  Total Private: 76464 ( 305856 Kb)

0358 MsMpEng.exe 26290 ( 105160 Kb)
0380 svchost.exe 4818 ( 19272 Kb)
0438 CcmExec.exe 4088 ( 16352 Kb)
0344 wlcrasvc.exe 2291 ( 9164 Kb)
0a08 wuauclt.exe 2171 ( 8684 Kb)
0070 WakeUpAgt.exe 1870 ( 7480 Kb)
01d0 winlogon.exe 1825 ( 7300 Kb)
0208 lsass.exe 1660 ( 6640 Kb)
066c FSysAgent.exe 1605 ( 6420 Kb)
0730 InoRpc.exe 1210 ( 4840 Kb)
06b8 HealthService.e 1210 ( 4840 Kb)
0d54 wmiprvse.exe 951 ( 3804 Kb)
04f4 spoolsv.exe 912 ( 3648 Kb)
02c8 svchost.exe 748 ( 2992 Kb)
0308 svchost.exe 543 ( 2172 Kb)
04a4 ati2evxx.exe 542 ( 2168 Kb)
02b8 ati2evxx.exe 506 ( 2024 Kb)
0fd0 wmiprvse.exe 501 ( 2004 Kb)
01fc services.exe 472 ( 1888 Kb)
01b0 csrss.exe 431 ( 1724 Kb)
042c svchost.exe 412 ( 1648 Kb)
03d8 svchost.exe 390 ( 1560 Kb)
014c wdfmgr.exe 384 ( 1536 Kb)
05d0 svchost.exe 309 ( 1236 Kb)
067c FwcAgent.exe 294 ( 1176 Kb)
0cc8 alg.exe 277 ( 1108 Kb)
0614 mscorsvw.exe 254 ( 1016 Kb)
0180 smss.exe 49 ( 196 Kb)
0004 System 7 ( 28 Kb)
062c wlcrdpsystem.ex 0 ( 0 Kb)

As you can see, just the straightforward command gives us plenty of information about our virtual memory usage.  Let’s modify the flags a bit:

1: kd> !vm 5

*** Virtual Memory Usage ***
Physical Memory: 523793 ( 2095172 Kb)
Page File: \??\C:\pagefile.sys
Current: 2095104 Kb Free Space: 2031992 Kb
Minimum: 2095104 Kb Maximum: 4190208 Kb
Available Pages: 389780 ( 1559120 Kb)
ResAvail Pages: 436684 ( 1746736 Kb)
Locked IO Pages: 54 ( 216 Kb)
Free System PTEs: 149380 ( 597520 Kb)
Free NP PTEs: 32766 ( 131064 Kb)
Free Special NP: 0 ( 0 Kb)
Modified Pages: 754 ( 3016 Kb)
Modified PF Pages: 753 ( 3012 Kb)
NonPagedPool Usage: 3230 ( 12920 Kb)
NonPagedPool Max: 65536 ( 262144 Kb)
PagedPool 0 Usage: 3862 ( 15448 Kb)
PagedPool 1 Usage: 458 ( 1832 Kb)
PagedPool 2 Usage: 445 ( 1780 Kb)
PagedPool 3 Usage: 471 ( 1884 Kb)
PagedPool 4 Usage: 460 ( 1840 Kb)
PagedPool Usage: 5696 ( 22784 Kb)
PagedPool Maximum: 92160 ( 368640 Kb)
Shared Commit: 6500 ( 26000 Kb)
Special Pool: 0 ( 0 Kb)
Shared Process: 2908 ( 11632 Kb)
PagedPool Commit: 5696 ( 22784 Kb)
Driver Commit: 2235 ( 8940 Kb)
Committed pages: 104454 ( 417816 Kb)
Commit limit: 1008403 ( 4033612 Kb)



Terminal Server Memory Usage By Session:

Session Paged Pool Maximum is 4096K
Session View Space Maximum is 49152K

Session ID 0 @ ba620000:
Paged Pool Usage: 0K
Commit Usage: 6412K

For this command, I elected to leave out the process statistics (0x1) and capture the terminal server memory usage information (0x4).  The result (0x5) shows me that there was only one active session – Session 0.  If I were to run this on a Terminal Server, I could see the information for the remote sessions as well.  Let’s now take a look at our other command - !memusage which we use to review physical memory use.  The flags for this command are somewhat similar to those for !vm but one thing to note is that the flags only apply to Windows XP and later operating systems.  For Windows 2000 systems, there are no additional parameters for !memusage:

Flag Function
0x0 General summary information plus a detailed description of the pages in the PFN database
0x1 Summary information about the modified no-write pages in the PFN database
0x2 Detailed information about the modified no-write pages in the PFN database
0x8 Displays only general summary information about memory use

So, here’s a snippet of !memusage with no flags:

1: kd> !memusage
loading PFN database
loading (100% complete)
Compiling memory usage data (99% Complete).
Zeroed: 281150 (1124600 kb)
Free: 0 ( 0 kb)
Standby: 108630 (434520 kb)
Modified: 754 ( 3016 kb)
ModifiedNoWrite: 0 ( 0 kb)
Active/Valid: 133277 (533108 kb)
Transition: 0 ( 0 kb)
Bad: 0 ( 0 kb)
Unknown: 0 ( 0 kb)
TOTAL: 523811 (2095244 kb)
Building kernel map
Finished building kernel map
Scanning PFN database - (100% complete)


Usage Summary (in Kb):
Control Valid Standby Dirty Shared Locked PageTables name
89e4a8b8 364 28868 0 0 0 0 mapped_file( $LogFile )
89c91168 0 1880 0 0 0 0 mapped_file( mscorlib.ni.dll )
899a31d8 0 636 0 0 0 0 mapped_file( mshtml.dll )
893933d0 0 52 0 0 0 0 mapped_file( ccmident.dll )
892bd2f0 0 68 0 0 0 0 mapped_file( wbemess.lo_ )
89c85220 0 2872 0 0 0 0 mapped_file( mscorwks.dll )

To get just the first piece of information, use the 0x8 flag:

1: kd> !memusage 8
loading PFN database
loading (100% complete)
Compiling memory usage data (99% Complete).
Zeroed: 281150 (1124600 kb)
Free: 0 ( 0 kb)
Standby: 108630 (434520 kb)
Modified: 754 ( 3016 kb)
ModifiedNoWrite: 0 ( 0 kb)
Active/Valid: 133277 (533108 kb)
Transition: 0 ( 0 kb)
Bad: 0 ( 0 kb)
Unknown: 0 ( 0 kb)
TOTAL: 523811 (2095244 kb)

With that, we’ve reached the end of this post.  The resources below as well as the debugging help file can provide you with more information.  Until next time …

Additional Resources:

- CC Hameed

Share this post :


Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi, Thanks for the great post.

    If you don't mind, I have a couple of beginner's questions:

    1. why / when / what situation, do we want to use !vm or !memusage?

    2. a practial example of what info that we should be looking at with the info provided, to help us figure out what type of problem we are debugging.

    thanks in advance for your time and help. :)