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:
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:
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:
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:
In the third part we'll see how to further zoom-in on the managed heaps and see what's going on inside.