Mapping the Memory Usage of .NET Applications: Part 2, VMMap and MemoryDisplay

July 18, 2011

6 comments

How can you map the memory usage of your .NET application? We’ll start with VMMap, a free Sysinternals tool that visualizes your process’ virtual address space. Below is VMMap’s output for an example process:

image

The type statistics give you a detailed overview of how memory usage is distributed – there are 240MB of DLLs, 50MB of managed heaps (of which only 10MB are committed), etc. In the bottom details view you can see each individual address range on the heap, including its type, size, committed size, and other details (such as DLL names for the "Image" type and file names for the "Mapped File" type).

Within the GC heap, VMMap features the ability to identify the various generations (and the Large Object Heap) within the GC segments:

image

In the VMMap output above, there are 1,916KB of "Unusable" memory—what’s wrong with it? Even though the VMMap documentation doesn’t say so clearly, "Unusable" memory regions are address ranges that cannot be allocated because of VirtualAlloc’s 64KB start address granularity guarantee (see the history of this decision).

Finally, for 32-bit processes, VMMap features a “Fragmentation View” in which you can see a visual representation of your memory space and zoom in on fragmented regions:

image

Note that virtual memory fragmentation is a real PITA for 32-bit managed processes. We’re not talking about internal fragmentation due to pinning – we’re talking about external fragmentation between GC segments; Maoni’s blog post What’s New in CLR 2.0 GC explains both phenomena.

How does this happen? The GC allocates virtual memory in large chunks, called segments, which are at least 16MB in size. As time elapses, segments are allocated and freed, and smaller chunks of memory fragment the virtual address space. At the extreme, you may get an out-of-memory exception when there is still lots of virtual memory available – the problem is that there isn’t enough consecutive memory to satisfy the GC’s allocation request for another segment. (VM hoarding is one alleviation option; another way for diagnosing these problems, even from a dump file, is !address –summary or !AnalyzeOOM.)

Another tool to get a visual view of virtual memory is an experimental solution by Microsoft’s John Allen posted on Tess Fernandez’ blog:

Screenshot3_MemoryDisplay

In the third part we’ll see how to further zoom-in on the managed heaps and see what’s going on inside.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

6 comments

  1. SvickJuly 18, 2011 ב 10:14 PM

    I seem to remember that VMMap couldn’t display CLR 4’s memory correctly. (I think it always showed Managed heap as empty.) Is that still the case?

    Reply
  2. GSAugust 1, 2011 ב 11:54 PM

    The screenshot does not appear to be correlating to description. It says 240MB in DLLs but on screenshot there is no indication which specific subset is taking 240MB.

    Reply
  3. Pratima December 2, 2011 ב 8:10 AM

    it allows to select either one process or all processes at a time and not like 2-3… 🙁

    Reply
  4. DavidApril 22, 2013 ב 9:45 PM

    I have an svchost.exe process that has been running for two days and it’s now showing 555,700k of “Unusable Memory” that is steadily increasing. The largest unusable chunk in that huge pile of lost VM is 60k and yes, there a zillion 60k chunks in that memory type.

    I’m on Vista Business, and that svchost is the one that handles netsvcs.

    The VMMap tool and your tutorials helped me find this insidious memory thief. My page file grows indefinitely until the system becomes unusable.

    Question: Now that I can see this using VMmap, is there more VMmap can tell me about that svchost.exe process, such as which DLL is growing the unusable memory, or is it time to move to a new tool or troubleshooting approach for the next step in tracking this down?

    thanks

    Reply
  5. Sasha GoldshteinApril 24, 2013 ב 9:08 AM

    @David:
    You can use a debugger to track individual allocations. In fact, because you know the size of the memory region being alloc’d, you can configure that breakpoint to only stop (or log) allocation call stacks for these sizes.

    Reply
  6. RahulAugust 22, 2016 ב 7:26 PM

    During memory testing, my team have attached vmmap to our application. On one our test systems, the unusable memory was not appearing under the committed Column. However, when we re-built the system (using Re-do), it suddenly did start appearing.

    Do you know when/how to set what memory will be registered by VMMap?

    Reply