3

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

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

我假设标记为“SmallAlloc”的 GC 是由常规分配(New Object())引起的,而标记为“Induced”的 GC 是由调用“System.GC.Collect”引起的。如果您认为我做出了不正确的假设,请告诉我。

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

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

4

2 回答 2

0

似乎您已经推断出 GC.Collect() 不是您的问题,但作为参考,我过去成功地在 GC.Collect 中放置断点,当时我可以从 Induced GC 计数器中看到肯定有诱导 GC正在发生。

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

于 2011-05-26T20:09:30.430 回答
0

我仔细查看了 PerfMonitor.exe 的输出。我不确定每个标记为“Induced”的 GC 实际上是由 System.GC.Collect 引起的。似乎所有 Gen 1 GC 都标记为 Reason="Induced",而所有 Gen 0 GC 都标记为 Reason="SmallAlloc"。Gen2 GC 标记为 Reason="LowMemory"。

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

于 2011-05-24T12:41:46.843 回答