将LOH中的对象固定是否会影响GC性能?

9

我了解到,在.NET中固定托管堆中的对象会影响GC性能,因为如果有固定的对象“挡道”,GC就无法压缩内存。但由于大对象堆根本不会被压缩,所以这不适用于LOH中的对象。 固定在LOH中的对象是否存在其他隐藏成本?或者我可以安全地固定LOH中的对象而不降低GC性能吗?

1个回答

5
好的,仅仅因为大对象堆(LOH)没有压缩并不意味着它没有被收集。LOH是可以被收集的,在其中固定一个对象会对未来的分配产生影响。
因为对象被固定,实际上会减少LOH中可用的内存量(与您持有引用一样)。当另一个请求分配大对象时,如果LOH中有太多的固定/持有引用,就可能出现无法分配更多大对象的问题。
在垃圾回收的标记和清除阶段进行标记时,CLR可能会将所有固定的引用都标记为根引用,因此在此收集过程中可能没有影响;如果有人保留了对大对象的引用,它将以相同的方式运行。
由于在LOH上进行解除分配的方式相同(块只是被标记为可用),因此此操作也不受影响。
最后,由于LOH没有被压缩,因此在GC期间永远不会在此堆上执行此操作,因此此处也不受影响。
总的来说,将对象引用固定到 LOH 上会明显影响 LOH 的分配,而 LOH 上的收集可能不会受到影响。
虽然我们不应忘记,在一般情况下,分配和持有大块内存可能会对系统产生后果,但这些评论严格是关于 LOH 的。

谢谢回答。我不确定我理解第二段的意思:为什么固定引用比保留引用要减少更多可用内存?我一直认为在 LOH 上分配某些东西本质上意味着寻找够大的空闲内存块或分配一个新段 - 如果是这样,任何活动块都应该被视为相同的,无论是否固定引用。 - Niki
@nikie:它不再这样做了,它只有相同的效果(如您所述)。我已经相应地更新了我的答案。这是一个小但重要的更改。 - casperOne

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