垃圾回收 - 跟踪 .NET 4.0 诱导 GC 的来源



我正在使用PerfMonitor.exe(http://bcl.codeplex.com/wikipage?title=PerfMonitor)来跟踪使用某些第三方库的.NET 4.0应用程序的一些.NET性能问题,其中一些是本机代码。

当我运行Perfmonitor GCTime报告时,它会列出各个GC并以多种方式对其进行分类。 报告中的一列称为"原因"。 一些GC有Reason="Induced",而另一些GC有Reason="SmallAlloc"。

我假设标记为"SmallAlloc"的GC是由常规分配(New Object())引起的,而标记为"诱导"的GC是由对"System.GC.Collect"的调用引起的。 如果您认为我做出了错误的假设,请告诉我。

我试图找到调用System.GC.Collect的代码,但我没有成功。 使用 MSVS 2010 专业版,我在 System.GC.Collection 中设置了一个断点,并通过编写包含对 System.GC.Collection 的调用的简单测试函数来确保此断点正常工作。 但是,我正在调整的应用程序不会在该断点处中断,这使我相信没有代码调用System.GC.Collect。

我在想也许有本机代码可以通过直接调用 mscorwks 中的本机函数来诱导 GC.dll并绕过 System.GC.Collect。 我看到System.GC.Collect调用_Collect在JitHelpers中.cpp这是在mscorwks中。 有没有办法在该函数中设置断点?

我仔细

观察了PerfMonitor.exe的输出。 我不确定每个标记为"诱导"的GC实际上是由System.GC.Collect诱导的。 似乎所有第 1 代 GC 都被标记为 Reason="Induced",而所有第 0 代 GC 都被标记为 Reason="SmallAlloc"。 第 2 代 GC 标记为 Reason="LowMemory"。

有一个用于跟踪 .NET 诱导 GC 的性能计数器。 我监控了该性能计数器,它在我的过程中没有显示任何诱导的GC。 所以我得出结论,Perfmonitor.exe误导了我。

看来你已经推断出了那个GC。Collect() 在这里不是您的问题,但作为参考,我已经成功地在 GC 中放置了断点。过去,当我可以从诱导 GC 计数器中看到肯定有诱导 GC 发生时收集。

您可以将断点位置设置为 System.GC.Collect 并试一试。使用这种策略,我有时会成功设置框架断点,有时不会。我不知道是因为方法/属性调用被优化了,还是其他原因。但它总是值得一试的。您可能需要执行一些操作,例如在"工具"->"选项"->"调试"部分中禁用"仅我的代码"。

最新更新