【发布时间】:2011-09-08 10:04:50
【问题描述】:
我在我的应用程序中遇到了一个问题,我看到了过多的 Gen 2 垃圾收集。从我一直在阅读的内容来看,Gen0 : Gen1 : Gen2 集合的比例应该是 100:10:1。我非常接近 1:1:1。每个集合似乎都是 Gen2 集合。我一直在试图找出造成这种情况的原因,但我运气不佳。我尝试过的事情:
使用 .NET Memory Profiler 查看正在创建的对象。我打开 Perfmon 向我显示第 2 代堆的大小,我尝试在它低时和高时拍摄快照,然后比较差异。这是部分成功的。然后 % Time in GC 似乎更低了,但是 Gen2 的集合仍然和 Gen1 一样多。
我在我的应用程序中禁用了一项主要功能,并发现这是导致问题的原因。不知道这有什么帮助,但我想我会提到我对代码中的问题所在有一个大致的了解。
我也尝试了其他工具。红门内存分析器。这也没有多大帮助。
所以这是我的问题:
是什么导致 CLR 在 Gen0 或 Gen1 上执行 Gen2 收集?我一直在阅读它可能是 LOH,但我已经确认这不是我的问题。
我还应该使用哪些其他故障排除技术?
编辑: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