【问题标题】:Excessive Gen 2 Collections过多的 Gen 2 集合
【发布时间】:2011-09-08 10:04:50
【问题描述】:

我在我的应用程序中遇到了一个问题,我看到了过多的 Gen 2 垃圾收集。从我一直在阅读的内容来看,Gen0 : Gen1 : Gen2 集合的比例应该是 100:10:1。我非常接近 1:1:1。每个集合似乎都是 Gen2 集合。我一直在试图找出造成这种情况的原因,但我运气不佳。我尝试过的事情:

  1. 使用 .NET Memory Profiler 查看正在创建的对象。我打开 Perfmon 向我显示第 2 代堆的大小,我尝试在它低时和高时拍摄快照,然后比较差异。这是部分成功的。然后 % Time in GC 似乎更低了,但是 Gen2 的集合仍然和 Gen1 一样多。

  2. 我在我的应用程序中禁用了一项主要功能,并发现这是导致问题的原因。不知道这有什么帮助,但我想我会提到我对代码中的问题所在有一个大致的了解。

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

所以这是我的问题:

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

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


编辑:2011 年 6 月 6 日

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


编辑:2011 年 6 月 7 日

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

【问题讨论】:

  • 您是否正在尝试解决并非真正问题的问题?您的应用运行缓慢还是内存不足?
  • 我应该提一下,看起来 Gen2 收集似乎以每秒 1 或 2 次的速度发生。
  • 嗯,我试图解决的最初问题是客户报告软件运行缓慢。我们查看了性能计数器,我注意到了这个问题。 GC 中的时间百分比平均约为 20%。我们有理由相信客户的问题更有可能是由他们的环境引起的,但我仍然想了解这里发生了什么。

标签: .net garbage-collection windbg


【解决方案1】:

有趣。事物在 GEN2 中仍然存在的事实可能意味着您对事物的持有量有点大 - 也许您有一些临时对象仍然可以被一个寿命更长的对象访问,这可能是由于事件订阅或捕获的变量闭包。

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

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

【讨论】:

  • 我正在创建很多对象。我可以从字节分配/秒计数器中看到。它非常尖。
  • 我创建的对象不应该存在很长时间,但它们是因为 GC 运行得太多。我认为这是我的主要问题。是什么导致 GC 运行如此频繁?
  • @Bryan - 内存压力,反过来又是由大量分配引起的;p 我意识到这听起来有点循环,但是嘿:我们不知道你的代码在做什么;p
  • 我也不知道它在做什么:)
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-10
    • 2022-12-01
    • 2011-01-20
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    相关资源
    最近更新 更多