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 (7)

  1. Ruth says:

    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.info

  2. daveblack says:

    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:

    1. 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

    2. What is in the "unclassified" category"?  How can I make any sense of that?

    3. Why are some of the categories, which appear to describe the same thing, have different values?  i.e. MEM_FREE and RegionUsageFree?

    4. 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!

  3. rafarah says:

    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:

    http://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,

    Roberto

  4. rafarah says:

    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,

    Roberto

  5. John says:

    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,

    John

  6. rafarah says:

    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