简体   繁体   English

当.NET不在垃圾收集(GC)中时,如何捕获.NET进程的进程内存转储

[英]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 (eg 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. 当捕获转储文件并对其进行分析时(例如在WinDbg中),我经常会收到警告:数据可能不准确,或者命令可能无法访问,因为当收集转储文件时,进程位于GC的中间。

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. 在进行内存分析时,我们经常这样做是因为进程中的内存很高而且内存压力很高,我猜这会强制.NET到GC。

How do I avoid taking dumps during a GC? 如何在GC期间避免转储? Is there a way to know when its safe to capture the dump file? 有没有办法知道何时可以安全地捕获转储文件?

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. 我不是这方面的专家,但我注意到你可以使用.NET运行时的性能计数器来监视一些有趣的事情 - 其中一个是垃圾收集器在上次收集时分配的字节数。 The description of Allocated Bytes/second in Performance Counters in the .NET Framework states: .NET Framework性能计数器中的Allocated Bytes/second说明:

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. 根据我的测试,如果您将性能监视器的更新间隔设置为1秒并仔细查看Allocated Bytes/second的指示器,则在收集完成后它似乎显示值0 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. 我通过在VS 2015中构建一个小应用程序来检查它,该应用程序能够显示是否正在进行垃圾收集。 The value of the indicator was different to 0 if it was the case. 如果是这样的话,指标的值不同于0。

Update (Thanks Thomas) 更新 (谢谢托马斯)

It is possible to use ProcDump for monitoring the performance counter and create the dump in an automated fashion. 可以使用ProcDump监视性能计数器并以自动方式创建转储。 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. 这样做的正确方法是: procdump ProcessName -s 1 -ma -pl "\\.NET CLR Memory(ProcessName)\\Allocated Bytes/second" 1000如果值低于procdump ProcessName -s 1 -ma -pl "\\.NET CLR Memory(ProcessName)\\Allocated Bytes/second" 1000 ,将触发转储。

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). 如果您不使用英文版操作系统,则必须找到性能计数器的正确语言特定名称(可以通过查看上面提供的MSDN链接并在那里切换到其他语言来完成)。 Eg the german name would be "\\.NET CLR-Speicher(ProcessName)\\Zugeordnete Bytes/Sek." 例如,德语名称为"\\.NET CLR-Speicher(ProcessName)\\Zugeordnete Bytes/Sek." .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM