ClrMD is a great tool to inspect a live executable or a memory dump. To dump all managed heap objects as summary you can use
https://blogs.msdn.microsoft.com/dotnet/2013/05/01/net-crash-dump-and-live-process-inspection/
var stats = from o in heap.EnumerateObjects()
let t = heap.GetObjectType(o)
group o by t into g
let size = g.Sum(o => (uint)g.Key.GetSize(o))
orderby size
select new
{
Name = g.Key.Name,
Size = size,
Count = g.Count()
};
foreach (var item in stats)
Console.WriteLine("{0,12:n0} {1,12:n0} {2}", item.Size, item.Count, item.Name);
That works great and is the equivalent of !DumpHeap -stat in Windbg with the SOS Extension. For regression testing it is often desireable to check after a test if objects were leaked. That looks like a perfect fit for the code above but unfortunately it produces false positives because there may be objects which are no longer rooted but they are still reported in the summary. That can lead to reported leaks although there are none.
SOS has mitigated this issue by addine to !DumpHeap the -live switch. What would be the equivalent ClrMD code to get only the live objects so regression tests only fail for a real reason?
I guess I need to use ClrType.EnumerateRefsOfObjectCarefully to walk the stack recursively until I find a root object (ClrHeap.EnumerateRoots) but that approach needs many temporary Hashsets to track recursive object graph. Is this the only way to do it or is there somewhere inside MS already a correct and well performing sample available (PerfView source?).