过多的第二代收藏

时间:2011-06-04 15:30:30

标签: .net garbage-collection windbg

我在我的应用程序中遇到问题,我看到过量的Gen 2垃圾收集。从我读过的内容来看,它听起来比较Gen0:Gen1:Gen2系列应该是100:10:1。我越来越接近1:1:1。每个系列似乎都是Gen2系列。我一直试图找出原因,但我没有太多运气。我尝试过的事情:

  1. 使用.NET Memory Profiler查看正在创建的对象。我打开了Perfmon,向我展示了Gen 2 Heap的大小,我试图在它很低时拍摄快照,当它很高时然后比较差异。这部分成功了。然后GC中的%Time似乎更低,但仍然有Gen1的Gen2集合。

  2. 我在我的应用程序中禁用了一个主要功能,发现它是造成问题的原因。不知道这有什么帮助,但我想我已经提到我有一个大概的想法在我的代码中的问题是什么。

  3. 我也尝试过其他工具。红门内存分析器。这也没有多大帮助。

  4. 所以这是我的问题:

    1. 是什么原因导致CLR在Gen0或Gen1上执行Gen2集合?我一直在读它可能是LOH,但我已经证实这不是我的问题。

    2. 我应该使用哪些其他故障排除技巧?


    3. 编辑:2011年6月6日

      它看起来与调用System.Diagnostics.PerformanceCounterCategory.GetInstanceNames()有关。我们有一个收集各种性能计数器的线程。看起来这最终会调用HKEY_PERFORMANCE_DATA的注册表读取和值“230”。这看起来像是“过程”类别。返回的数据是一个65000字节的字节数组。虽然这个数字小于85000,但似乎这里的东西已经被放在了LOH上。我在WinDbg上放了一个断点“mscorwks!svr :: gc_heap :: allocate_large_object”。


      编辑:2011年6月7日

      这肯定与频繁获取性能计数器数据有关。获取130,000字节的字节数组只是为了从计数器读取值。因为我经常这样做,所以它创造了很多Gen2系列,因为它们都进入了LOH。我正在考虑使用P / Invoke语句来获取计数器值。

2 个答案:

答案 0 :(得分:1)

有趣。事物存在于GEN2这一事实可能意味着你要抓住一些东西 - 也许你有一个临时对象仍然可以被一个寿命较长的对象访问,可能是由于事件订阅或捕获的变量闭包。

听起来分配本身可能也很高;注意大量的临时对象(以某种方式可达)。

但事件是IMO最可能的解释。查看您是否未能从事件中取消订阅临时对象。

答案 1 :(得分:0)

事实证明,我不需要读取那些性能计数器值。我刚刚删除它们,事情要好得多。