【问题标题】:What advantage is there to only collecting large-object-heap objects with Generation 2?仅使用第 2 代收集大对象堆对象有什么好处?
【发布时间】:2011-06-24 17:07:27
【问题描述】:

我知道分代垃圾收集可以提高性能,因为

  1. 在非 Gen2 集合中,任何对象最多只能移动两次,Gen2 集合很少见。
  2. 如果系统正在执行 Gen0 收集,并且自上次 Gen0 收集后尚未写入对象(Gen1 或 Gen2),则系统不必扫描该对象以标记其中的任何引用(因为它们将都是 Gen1 或 Gen2)。同样,如果系统正在执行 Gen1 收集,它可以忽略自上次 Gen1 收集以来未写入的任何对象。由于垃圾收集的大部分工作是扫描对象,因此减少扫描时间是一个很大的胜利。

不过,我很好奇,从 Gen1 垃圾收集中省略大对象有什么性能优势?大对象即使被垃圾收集器扫描也不会被重新定位,我希望 Gen1 集合仍然必须扫描它们的内容,除非或直到两个连续的 Gen1 集合发生而没有干预对象写入。

是否有一些我没有看到的性能优势?

【问题讨论】:

    标签: .net garbage-collection large-object-heap


    【解决方案1】:

    不过,我很好奇,从 Gen1 垃圾收集中省略大对象有什么性能优势?

    有两件事-

    首先,大型对象(大到足以在 LOH 上)往往具有更长的生命周期。短暂的大对象很少见,在需要的情况下,您通常可以重用它们。通过不扫描,您有效地避免了几乎总是会导致保留对象的扫描。这往往会给您带来性能上的胜利。

    此外,为了有效地处理 Gen1 中的对象,并获得 Gen1 提供的许多优势,它们需要能够压缩。分代收集器的一大优势是您正在压缩最新的分配,这有助于降低内存压力,因为碎片往往表现得更好。 Gen1 中的大对象会导致性能或内存问题,因为它们要么需要压缩(现在,大对象没有被压缩,因为“移动”它们的成本很高),要么它们会导致额外的碎片蔓延。

    【讨论】:

    • 已知 LOH 会导致在某些情况下导致 OutOfMemoryExceptions 的碎片问题。我知道压缩很昂贵,但作为程序的开发者,至少让我可以选择打开它。
    • @DavidN:我遇到了 LOH 碎片问题,我怀疑一些应该是短暂的(但当然不是)的对象可能会起作用。可以肯定的是,在抛出 OutOfMemoryException 之前压缩 LOH 会使碎片化问题变得更少,但我很好奇该策略的基本原理。
    • @supercat:我找到的关于这个主题的最佳文章。 simple-talk.com/dotnet/.net-framework/…
    • @DavidN:可能的基本原理是,如果一个人只在 L2 收集期间收集 LOH 对象,那么一个人将一次收集更多的对象,从而产生更大的洞。我可以看出这一点,但是等到应用程序在清理它之前产生了一个有价值的垃圾,这意味着一个人保留的东西里面会有很好的整合漏洞,但会分散在一个 gig 上。更频繁地腾出可用空间会导致更快地填充漏洞,但碎片不会在内存中蔓延太多。
    • @DavidN:我读过那篇文章(同意这篇文章很好,顺便说一句——谢谢),但我认为我没有看到任何解释为什么 LOH 集合被推迟到 Gen2。在我看来,延迟 LOH 收集的真正效果是增加了应该短命的大对象存活足够长的时间以便在它们之后放置较小的长寿命对象的可能性。
    猜你喜欢
    • 1970-01-01
    • 2016-02-11
    • 2012-10-09
    • 2023-03-17
    • 2015-08-10
    • 2011-06-20
    • 1970-01-01
    • 2012-10-02
    相关资源
    最近更新 更多