问题描述
在捕获转储文件并对其进行分析时(例如在WinDbg中),我经常收到警告说数据可能不准确,或者命令可能无法访问,因为转储文件时进程正在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.
在做内存分析时,我们经常这样做是因为进程上的内存很高,内存压力很大,我猜这迫使.NET经常进行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.
如何避免在 GC 期间进行转储?有没有办法知道何时可以安全地捕获转储文件?
How do I avoid taking dumps during a GC? Is there a way to know when its safe to capture the dump file?
推荐答案
我不是这方面的专家,但我注意到您可以使用 .NET 运行时的性能计数器来监控一些有趣的事情——其中之一是垃圾收集器在上次收集期间分配的字节数.Allocated Bytes/second的描述rel="noreferrer">.NET Framework 中的性能计数器 状态:
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.
根据我的测试,如果您将性能监视器的更新间隔设置为 1 秒,并仔细查看 Allocated Bytes/second
的指标,它似乎显示了一个 <收集完成后的code>0.所以我假设,无论收集是否正在进行,您都可以从这个值中得出.
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.
我通过在 VS 2015 中构建一个小应用程序来检查它,该应用程序能够显示是否正在进行垃圾收集.如果是这种情况,则指标的值不为0.
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.
更新(感谢 Thomas)
Update (Thanks Thomas)
可以使用 ProcDump 来监控性能计数器和以自动方式创建转储.这样做的正确方法是: procdump ProcessName -s 1 -ma -pl ".NET CLR Memory(ProcessName)Allocated Bytes/second" 1000
如果值下降将触发转储一千以下.
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.
如果您不是在英文版操作系统上运行,则必须找出性能计数器的正确语言特定名称(可以通过查看上面提供的 MSDN 链接并切换到其他语言来完成那里).例如.德国名字会是 ".NET CLR-Speicher(ProcessName)ugeordnete Bytes/Sek."
.
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)ugeordnete Bytes/Sek."
.
这篇关于当 .NET 不在垃圾收集 (GC) 中间时如何捕获 .NET 进程的进程内存转储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!