Special Command—Peeking Memory Addresses Using !address
Let’s say that you get a memory address and you want to know if it’s from the heap, the stack, or someplace else. Or yet, let’s say you have a .NET application consuming lots of memory, and you want to get a better understanding of this memory consumption.
The !address command is helpful in both situations mentioned above and probably others not mentioned in this article.
Usage:
!address <address> ß gives you information about the address type.
!address –summary ß displays all addresses and a summary at the end.
To interpret the results follow this table:
RegionUsageIsVAD |
The "busy" region. This region includes all virtual allocation blocks, the SBH heap, memory from custom allocators, and all other regions of the address space that fall into no other classification. |
RegionUsageFree |
The available memory in the target's virtual address space. This memory includes all memory that has not been committed or reserved. |
RegionUsageImage |
The memory region that mapped images of binaries use. |
RegionUsageStack |
The memory region that is used for the stacks owned by the threads in the target process. |
RegionUsageTeb |
The memory region that is used for the thread environment blocks (TEBs) for all threads in the target process. |
RegionUsageHeap |
The memory region that is used for the heaps that the target process owns. |
RegionUsagePageHeap |
The memory region that is used for the full-page heap that the target process owns. |
RegionUsagePeb |
The memory region that is used for the process environment block (PEB) of the target process. |
RegionUsageProcessParametrs |
The memory region that is used for the startup parameters of the target process. |
RegionUsageEnvironmentBlock |
The memory region that is used for the environment block of the target process. |
Examples:
!address <address>
!address –summary
ProcessParameters 003e1860 in range 003e0000 004b0000
Environment 003e0808 in range 003e0000 004b0000
-------------------- Usage SUMMARY --------------------------
TotSize ( KB) Pct(Tots) Pct(Busy) Usage
3b09000 ( 60452) : 02.88% 41.28% : RegionUsageIsVAD ß Location where .NET allocates heaps.
770f1000 ( 1950660) : 93.02% 00.00% : RegionUsageFree ß Not committed memory or not reserved memory.
46ff000 ( 72700) : 03.47% 49.65% : RegionUsageImage
6ff000 ( 7164) : 00.34% 04.89% : RegionUsageStack ß Used for stacks.
7000 ( 28) : 00.00% 00.02% : RegionUsageTeb ß Used for Thread Environment Block.
5f0000 ( 6080) : 00.29% 04.15% : RegionUsageHeap ß Heaps from native code allocations.
0 ( 0) : 00.00% 00.00% : RegionUsagePageHeap
1000 ( 4) : 00.00% 00.00% : RegionUsagePeb
0 ( 0) : 00.00% 00.00% : RegionUsageProcessParametrs
0 ( 0) : 00.00% 00.00% : RegionUsageEnvironmentBlock
Tot: 7fff0000 (2097088 KB) Busy: 08eff000 (146428 KB)
-------------------- Type SUMMARY --------------------------
TotSize ( KB) Pct(Tots) Usage
770f1000 ( 1950660) : 93.02% : <free>
46ff000 ( 72700) : 03.47% : MEM_IMAGE
181f000 ( 24700) : 01.18% : MEM_MAPPED
2fe1000 ( 49028) : 02.34% : MEM_PRIVATE
-------------------- State SUMMARY --------------------------
TotSize ( KB) Pct(Tots) Usage
5d48000 ( 95520) : 04.55% : MEM_COMMIT
770f1000 ( 1950660) : 93.02% : MEM_FREE
31b7000 ( 50908) : 02.43% : MEM_RESERVE
Largest free region: Base 04950000 - Size 5ee50000 (1554752 KB)
Comments
Anonymous
March 17, 2009
PingBack from http://blog.a-foton.ru/index.php/2009/03/18/special-command%e2%80%94peeking-memory-addresses-using-address/Anonymous
March 31, 2009
I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often. Ruth http://ramupgrade.infoAnonymous
November 08, 2010
Hi Roberto, I have a newer version of WinDbg (6.12.0002.633) and have different output than what you describe above. Could you please help me reconcile some of the pieces? My output: 0:000> !address -summary Failed to map Heaps (error 80004005) --- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal <unclassified> 6670 465d5000 ( 1.099 Gb) 95.67% 95.67% Image 1096 311d000 ( 49.113 Mb) 4.17% 4.17% Stack 75 170000 ( 1.438 Mb) 0.12% 0.12% TEB 75 4b000 ( 300.000 kb) 0.02% 0.02% NlsTables 1 24000 ( 144.000 kb) 0.01% 0.01% CsrSharedMemory 1 7000 ( 28.000 kb) 0.00% 0.00% PEB 1 1000 ( 4.000 kb) 0.00% 0.00% --- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal 7919 498d9000 ( 1.149 Gb) 100.00% --- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal 7919 498d9000 ( 1.149 Gb) 100.00% 100.00% --- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal --- Largest Region by Usage ----------- Base Address -------- Region Size ---------- <unclassified> 27f0000 be72000 ( 190.445 Mb) Image 7caf0000 5df000 ( 5.871 Mb) Stack 5d000 13000 ( 76.000 kb) TEB 7ff0f000 1000 ( 4.000 kb) NlsTables 7ffb0000 24000 ( 144.000 kb) CsrSharedMemory 7f6f0000 7000 ( 28.000 kb) PEB 7ffdd000 1000 ( 4.000 kb) Some of them seem obvious, if not please correct me - but others seem to be missing & cryptic: Old format --> My format ???? --> <unclassified> RegionUsageImage --> Image RegionUsageStack --> Stack RegionUsageTeb --> TEB ???? --> NlsTables ???? --> CsrSharedMemory RegionUsagePeb --> PEB A couple of questions:
- I have no entries for any of the following so what do they map to: RegionUsageIsVAD RegionUsageFree RegionUsageHeap RegionUsagePageHeap RegionUsageProcessParameters RegionUsageEnvironmentBlock MEM_IMAGE (it's also different than the number in RegionUsageImage???) MEM_MAPPED MEM_PRIVATE MEM_COMMIT MEM_FREE (it's different than RegionUsageFree???) MEM_RESERVE
- What is in the "unclassified" category"? How can I make any sense of that?
- Why are some of the categories, which appear to describe the same thing, have different values? i.e. MEM_FREE and RegionUsageFree?
- Is there any way to determine the last time a GC occurred from a full memory dump? For which GC? Thank you for your time!
Anonymous
November 08, 2010
Hi Dave, !address -? should give you the information from question #1. ;-) Same for question #2. You caught me on question #3. I have to spend some time researching to answer this question so you may want to use our discussion list to ask this question: www.microsoft.com/.../default.aspx For question #4 I don't think it's possible to get this information from a dump file. From a Live Debugging we could use breakpoints and track it but from a dump file I don't see how... anyway give me some time and I'll get more information about it. Thanks, RobertoAnonymous
November 08, 2010
Hi Dave, This is the information I got related to question #4: Not possible with public symbols but in .NET 4.0 the CLR (including the GC) is heavily instrumented so using ETW tracing you can get some really good trace data from the GC (timeline). Thanks, RobertoAnonymous
March 15, 2011
Hi rafarah, could you help me: I can't resolve <unclassified> from the !address -summary output. Sould i involve somthing in the symbol path to make <unclassified> resolve? Thanks, JohnAnonymous
March 16, 2011
Hi John, Please, make sure you're using the latest debugger and copy and paste the output here so we can take a look. Thanks, Roberto