.Net垃圾收集标记阶段和巨大的链表

时间:2011-06-14 06:22:11

标签: c# .net garbage-collection

如果有一个包含4M +节点的链表,那么每次构建图表时标记阶段是否需要遍历整个列表?在这种情况下是否应用了任何优化?在普通的视线中,它看起来效率不高。有没有办法验证GC是否遍历整个列表?

TIA。

3 个答案:

答案 0 :(得分:2)

是的,它需要遍历整个对象图。我不记得怎么可能有任何优化,说实话......但它不需要在每个节点上做很多事情。我怀疑,大部分时间都可能花在等待内存上,因为很明显它会在缓存中燃烧。当然,当链接列表在gen2中结束时(如果你分配了数百万个节点,其中大部分节点将很快在gen2中),那么它只需要很少这样做。

如果这是您的应用程序最合理的数据结构,我会暂时使用它,但使用性能监视器等跟踪垃圾收集的性能损失。如果结果是一个问题,您可以考虑替代战略。

答案 1 :(得分:2)

Jon说的话。

此外,一旦对象在Gen2中结束,可用的优化(在Windows上但不在其他平台IIRC上)是GC可以向内核注册以通知给定页面的内存。如果GC事件之间的页面保持不变,则无需重复某些工作。

答案 2 :(得分:2)

正在进行一项非常重要的优化。 .NET GC是分代的,gen2中的数据很少遍历。

对于大型数据结构(例如巨大的链接列表),您的大部分数据将很快以gen2结束,而GC很少会访问它。

此外,GC仅在收集期间遍历实时数据,“免费”收集死数据。因此,当您的列表无法访问时(或者如果它的大多数节点,但不是所有节点都可以),那么GC将能够基本上免费收集数百万个节点。