PSSCor2: GC Heap Analysis Commands
In our previous trip to PSSCor2-land, we’ve seen some object inspection commands tailored for ADO.NET and ASP.NET applications. This time, let’s take a step back and use some commands that display and analyze the managed heap.
The fundamental !DumpHeap command receives a minor facelift in PSSCor2—it has some new parameters. One welcome addition is the –gen parameter, which filters the output by a certain GC generation. Another great idea is the –random switch that prints every 1000th object so that your screen doesn’t get flooded with instances and so that you can inspect a random sampling. Finally, there’s also the –l switch, which limits the output to a certain number of objects from each GC heap.
For example, here are the LOH objects on my heap (note that the output includes natural LOH fragmentation):
0:006> !dumpheap -stat -gen 3
Loading the heap objects into our cache.
total 53,999 objects
Statistics:
MT Count TotalSize Class Name
0x00832328 44 704 Free
0x001a84f0 43 84,760 System.Object[]
Total 87 objects, Total size: 85,464
Another neat command is called !GCRef. Despite the similarity to !gcroot, this command shows you both references to the object (parents) and references from the object (children), even if the object is no longer rooted. Note that this command performs a complete heapwalk, so it might take a significant amount of time to complete.
For example, here is the list of an employee’s managers (assuming that the Employee class representing a manager has a reference to their direct reports):
0:003> .foreach (mgr {!gcref -shortparent 02500b38}) {!dumpfield -field _name -string mgr}
David
Kate
Next, the neat !CLRUsage command displays the commit and reserve sizes of the GC heaps, similarly to !eeheap –gc. Here are the two outputs side-by-side—you’d probably agree that the former is more readable:
0:003> !CLRUsage -v
Native Heap for .NET: 0x00470000
Number of GC Heaps: 1
seg base start end commit reserved
02470000 02471000 02471024 000c2000 00f3e000
seg base start end commit reserved
03470000 03471000 034764a0 00012000 00fee000
Total Size 0xbc494(771,220)
------------------------------
GC Heap Size 0xbc494(771,220)
Total Commit Size 000d4000 (0 MB)
Total Reserved Size 01f2c000 (31 MB)
Initial reservation type:
Initial Allocation Size: 0 (0) (0 MB)
Reserved Memory Size: 2000000 (33,554,432) (32 MB)
Reserved Memory Limit Size: 2000000 (33,554,432) (32 MB)
0:003> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x02471018
generation 1 starts at 0x0247100c
generation 2 starts at 0x02471000
ephemeral segment allocation context: none
segment begin allocated size reserved
02470000 02471000 02527ff4 0x000b6ff4(749,556) 00f3e000
Large object heap starts at 0x03471000
segment begin allocated size reserved
03470000 03471000 034764a0 0x000054a0(21,664) 00fee000
Total Size 0xbc494(771,220)
------------------------------
GC Heap Size 0xbc494(771,220)
Finally, I covered additional GC-related commands in PSSCor2 in a surprisingly old set of posts about the Silverlight SOS (!ListNearObj, !GCWhere, and !HeapStat). The same commands are now part of the CLR 4.0 SOS, but if you want to use them with a CLR 2.0 process, PSSCor2 gives you just that.