如果第2代被填满,垃圾收集期间会发生什么?

时间:2009-05-27 19:21:44

标签: c# .net garbage-collection

我正在重新阅读 CLR via C# ,并对.NET中的垃圾收集有一些疑问。在本书中,在填充第0代之后,垃圾收集开始并将所有未完成的对象引用移动到第1代。

第1代被填满时也是如此。但是当第二代被填满时会发生什么?没有其他代移动参考。第2代的大小是否由CLR扩展?

3 个答案:

答案 0 :(得分:20)

是的,如果可以,它将扩大第2代的规模。如果没有更多可用空间,您将获得OutOfMemoryException

答案 1 :(得分:3)

不同代的垃圾收集不是关于具有特定大小,而是关于垃圾的年龄。没有一代人有我所知的尺寸限制。

答案 2 :(得分:3)

根据我的理解,只有一个堆(具有讽刺意味的是,它通常被描述为堆栈)。对象被提升到第1代,而不是在第0代填充时,但是当它们在集合中存活时。简而言之,引用不会“移动”,用于标识生成结束位置的位置会被移动。

当堆接近满时,会发生一些事情:

  1. 收集每一代,从0开始到2结束。
    • 如果第0代的集合足够,则不会收集第1代和第2代。
    • 如果第0代的集合不充分,但第1代的集合是,则不会收集第2代。
  2. 堆被压缩(间隙被移除)
  3. 促进世代
    • 第1代幸存者被标记为第2代。
    • 第0代幸存者被标记为第1代。
  4. 然后将存在集合的对象移动到第0代(如果这是它们的第一个收集周期)或第2代(如果它们存活了多个集合)。这样做是为了提高效率,以确保我们不会经常尝试收集长寿命的物体。

    您不会以特定代的方式耗尽空间。 See this article有一个很好的解释。