Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture a process memory dump of a .NET process when .NET is not in the middle of a garbage collection (GC)

When capturing a dump file and analyzing it (e.g. in WinDbg), I often get the warning that the data may not be accurate, or commands may not be accessible, because the process was in the middle of GC when the dump file was collected.

When doing memory analysis, we often do it because the memory on the process is high and memory pressure is high which I guess forces .NET to GC frequently.

How do I avoid taking dumps during a GC? Is there a way to know when its safe to capture the dump file?

like image 521
Mark Avatar asked Nov 12 '15 16:11

Mark


1 Answers

I am no expert in this area but I've noticed that you can use the performance counters of the .NET runtime for monitoring some interesting things - one of them is the number of bytes that has been allocated by the garbage collector during it's last collection. The description of Allocated Bytes/second in Performance Counters in the .NET Framework states:

Displays the number of bytes per second allocated on the garbage collection heap. This counter is updated at the end of every garbage collection, not at each allocation. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval.

According to my tests, if you set the update interval of the performance monitor to 1 second and take a good look at the indicator for Allocated Bytes/second, it seems to show a value of 0 after a collection has completed. So I would assume, that you can derive from this value whether a collection is in progress or not.

I checked it by building a small application in VS 2015 which has the ability to show whether there is a garbage collection in progress. The value of the indicator was different to 0 if it was the case.

Update (Thanks Thomas)

It is possible to use ProcDump for monitoring the performance counter and create the dump in an automated fashion. The correct way of doing so would be: procdump ProcessName -s 1 -ma -pl "\.NET CLR Memory(ProcessName)\Allocated Bytes/second" 1000 which would trigger the dump if the value drops below one thousand.

This should work as the value is only zero if there is no garbage collection going on.

If you are not operating on an english version of the operating system you will have to find out the correct language specific name of the performance counter (can be done by looking at the MSDN-link provided above and switching to a different language there). E.g. the german name would be "\.NET CLR-Speicher(ProcessName)\Zugeordnete Bytes/Sek.".

like image 176
Markus Safar Avatar answered Sep 30 '22 11:09

Markus Safar