我们的多线程应用程序做了冗长的计算循环。平均来说,它需要大约29秒才能完成一个完整周期。在那段时间内,.NET性能计数器% time in GC占到8.5%。它全部由Gen 2系列产品组成。什么会导致性能改进?时间GC,汇集
为了提高性能,我们实现了我们的大对象池。我们实现了100%的娱乐率。整个周期现在平均只需要20秒。 GC中的%时间显示0.3 ... 0.5%之间。现在,GC只执行Gen 0集合。
让我们假设,该池是有效地实现,而忽略附加花费的时间执行。比我们的表现改善了大约33%。这与以前的8.5%的GC值有什么关系?
我有一些假设,我希望可以确认,调整和修订:
1)(如果我没有看错),并测量2次的关系“在GC时间”跨越:
- 2个GC周期和用于最后一个完整GC周期
- 时间之间的时间,该值被包括在第一范围。什么是不包括在第二时间跨度
,将停止和重新启动工作线程阻塞GC的开销。但是,这怎么可能达到整个执行时间的20%呢?
2)通常阻断线程GC可以胎面之间引入争用?这只是一个想法。我无法通过VS并发分析器来确认。
3)与此相反,它可以确认页面未命中(数性能计数器:内存 - 页面错误秒)> /为比用于与应用的UNPOOLED应用(25.000每秒)显著更高低GC率(每秒200次)。我可以想象,这也会带来很大的改善。但是,什么可以解释这种行为?难道是因为频繁的分配会导致虚拟内存地址空间中的一个更大的区域被使用,因此难以保存到物理内存中?那么如何衡量这个原因呢?
BTW:GCSettings.IsServerGC =假,.NET 4.0,64位,Win7上,4GB,英特尔酷睿i5运行。 (很遗憾的大问题..;)
我很犹豫回答你的问题,因为缺少很多信息给你一个真正的答案。 无论如何 - 总体性能改进*可能是由于: 1.减少GC时间(计算为〜8.0%=〜2秒)2.您所有的时间不必重新创建那些真正大的物体,因为它们现在已经有效地汇集了。这可能会非常昂贵,而且如果您将8.5%的时间花费在GC上,可能会非常昂贵。 – NightDweller 2011-04-10 16:51:09
@NightDweller感谢您的评论。这些对象是'唯一'的大数组。汇集它们所节省的唯一时间是最初清除它们所需的时间(将其元素设置为0)。另一方面,我认为在任何托管堆分配中,预计成本更高。 – user492238 2011-04-10 17:04:23
在某些情况下分配可能会很昂贵 - 如果您经常重新分配,并且需要长时间连续的内存块,这些内存块可能会因为碎片而变得很少。但是我必须承认它似乎并不全是可能的。 您是否尝试在代码上运行一个分析器? (之前/之后),应该给你一个非常明确的答案,以改善... – NightDweller 2011-04-10 21:40:16