【发布时间】:2011-08-19 12:25:25
【问题描述】:
我读过托管堆中的固定对象会影响 .NET 中的 GC 性能,因为如果有固定对象“挡道”,GC 将无法压缩内存。但由于大对象堆无论如何都不会被压缩,这不应该适用于 LOH 中的对象。固定 LOH 中的对象是否还有其他隐藏成本?或者我可以在不降低 GC 性能的情况下安全地将对象固定在 LOH 中吗?
【问题讨论】:
我读过托管堆中的固定对象会影响 .NET 中的 GC 性能,因为如果有固定对象“挡道”,GC 将无法压缩内存。但由于大对象堆无论如何都不会被压缩,这不应该适用于 LOH 中的对象。固定 LOH 中的对象是否还有其他隐藏成本?或者我可以在不降低 GC 性能的情况下安全地将对象固定在 LOH 中吗?
【问题讨论】:
嗯,大对象堆 (LOH) 没有被压缩并不意味着它没有被收集。 The LOH is collected 并将对象固定在那里将对未来的分配产生影响。
因为一个对象是固定的,它有效地减少了 LOH 中可用的内存量(就像你持有一个引用一样)。当发出另一个分配大对象的请求时,如果 LOH 中有太多固定/保留的引用,您可能会遇到分配更多大对象的问题。
当在垃圾收集的标记和清除部分完成标记时,CLR 可能会将 所有 固定为根的引用标记,因此在这部分收集期间可能没有影响;如果有人保留对大对象的引用,它的行为也会相同。
由于在 LOH 上解除分配的方式相同(块被简单地标记为可用),因此此操作也不受影响。
最后,由于 LOH 没有被压缩,这个操作在 GC 期间永远不会发生在这个堆上,所以这里不受影响。
总之,LOH 上的分配肯定会受到对 LOH 上对象的引用的影响,而 LOH 上的集合很可能不会。
虽然我们不要忘记分配和保存大块内存通常会对系统产生影响,但这些 cmets 严格来说是关于 LOH。
【讨论】: