CLR 4.0中垃圾回收的改进

9
最近我运行了Andrew Hunter在他的博客"The Dangers of the Large Object Heap"提供的示例,编译使用的是.NET 4,我得到了以下数字:

使用大块: 分配了622Mb
使用大块,频繁垃圾回收: 分配了582Mb
只使用小块: 分配了1803Mb
使用大块,大块不增长: 分配了630Mb

如果相同的代码编译为.NET 2.0,我几乎得到了文章中提到的数字:

使用大块: 分配了21Mb
使用大块,频繁垃圾回收: 分配了26Mb
只使用小块: 分配了1811Mb
使用大块,大块不增长: 分配了707Mb

这种显著改进的原因是什么?

代码是针对x86平台编译并在Windows 7上运行。

3个回答

4

4

有些事情发生了改变,但这是个秘密,我找不到任何相关信息。不要过度关注它。代码示例经过手动调整,使CLR 2的大对象堆看起来尽可能糟糕。即使是算法上的微小改变,也可能受到博客文章的启发,产生非常大的影响。


同意。这个问题是想找出有哪些差异,因为我认为所提出的更改都不可能以这种方式影响数字。 - Eugeniu Torica

2
我认为微软可以采取一些简单的措施来改进内存分配器,大大减少LOH碎片化,而不需要进行重大改动,例如将分配大小向上舍入到某个倍数(如4K)。鉴于最小的非静态LOH对象为85K,这最多只会损失5%的有用空间,但可以减少不同大小的对象和空隙数量。顺便说一句,我真的不相信强制所有大对象都进入LOH(也许可以在创建对象时指定是否应该进入LOH),我可以理解将小对象与大对象分开,一旦它们达到Level 2,但有足够的情况是大对象被创建并且被遗弃,强制它们进入Level 2似乎是适得其反。

双精度数组在 LOH 中的大小远低于 85K,但四舍五入仍然是一个好的理念。 - Ian Ringrose
我对微软的一些决策感到非常困惑。显然,将双精度数组推送到LOH的原因是因为LOH对象在8字节边界上对齐,而普通堆对象则不是。我认为特殊处理大小不超过指针的对象,使它们直接存储在堆描述符表中(取代指针),然后将所有堆对象舍入到下一个缓存行大小,无论它们是否包含任何双精度数,这样做会更有意义。 - supercat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接