This article is not meant to be comprehensive. Digging deep into heap dumps is a science and an art. This is meant to get you started, particularly if you’re new to .Net like I was not too long ago.
First of all, how do you get a process dump? There are numerous ways, but here’s the simplest one: open Task Manager and right-click the offending process and select “Create dump file”. You can search the web for the automated ways.
DebugDiag is a wonderful tool that runs a number of analyses for common issues on your dump and you don’t need to lift a finger or understand how it works. That’s why you should start with that. If it doesn’t expose your issue, you go on to the more manual tools.
Another neat thing about DebugDiag is that it produces a HTML report of the scans it ran and their results. This allows you to easily share findings with your team.
It’s a standalone tool with a standard Windows installer, so just install and run. It’s pretty self-explanatory.
WinDbg is a very comprehensive tool for debugging on Windows.
There are actually two WindDbg’s - the regular one and WinDbg Preview. If you don’t know the regular one already, I recommend Preview. It has a much different and friendlier UI and will become the default at some point. I haven’t had any issues with it.
WinDbg is a rich tool with extensive documentation. https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/getting-started-with-windows-debugging can point you in the right direction. Stefan Geiger also has a neat WinDbg Cheat Sheet for .NET Developers.
I’ll just throw out a few commands here that’ll help you get started and get a feel for it, and that helped me track down a tricky hang recently. If you’re lucky, they might already reveal the issue you’re debugging.
!dumpheap -stat
prints something like
00007ff89984fd10 511 57232 System.Runtime.Caching
.MemoryCacheEntry
00007ff89f24b208 14640 351360 System.SizedReference
00007ff899850930 14640 351360 System.Runtime.Caching
.MemoryCacheEqualityComparer
00007ff89984fef8 14640 351360 System.Runtime.Caching.Sref
00007ff89984f8f0 14640 468480 System.Runtime.Caching
.GCHandleRef`1[[System.Runtime.Caching.MemoryCacheStore,
System.Runtime.Caching]]
00007ff89984da50 14640 468480 System.Runtime.Caching
.UsageBucket[]
Threads
!threads // show
~2s // show details of a particular one
WinDbg supports extensions to load additional functionality at runtime. There are three you probably want to try: SOS is a must for debugging managed code, SOSEX and MEX provide useful helpers.
SOS “helps you debug managed programs in Visual Studio and in the Windows debugger (WinDbg.exe) by providing information about the internal Common Language Runtime (CLR) environment”. It comes with .Net but you need to load it in WinDbg:
!load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll)
It provides a number of essential commands whose names are mostly self-explanatory:
!sos.analyzeOOM
!sos.gcroot
!sos.finalizequeue
!sos.threadpool
!sos.threads
!sos.threadstate
Next is SOSEX. Download and run
!load …\sosex.dll
I liked the deadlock detection and the Finalizer queue analysis:
!dlk
!finq -stat
!finalizequeue
Finally, you might want to try Microsoft’s MEX.
MEX Debugging Extension for WinDbg can help you simplify common debugger tasks, and provides powerful text filtering capabilities to the debugger.
!load mex.dll
!mex help
will get you started.