追踪.NET 4.0诱导GC的来源

时间:2011-05-24 01:02:45

标签: .net garbage-collection profiling memory-profiling

我正在使用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。有没有办法在该函数中设置断点?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

似乎你已经推断GC.Collect()不是你的问题,但作为参考,我已经成功地在GC.Collect中设置了断点,当我从Induced GC计数器中看到有肯定会诱发GCs的发生。

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