垃圾收集中的几代人是什么?

时间:2010-02-13 12:57:08

标签: .net garbage-collection

我不明白垃圾收集环境中的“世代”是什么。有人可以用简单的语言解释一下吗?

3 个答案:

答案 0 :(得分:52)

来自Understanding Garbage Collection in .NET

  

<强>代

     

世代垃圾收集器   更多地收集短寿命的物品   经常比较长寿的。   短期对象存储在   第一代,第0代   更长寿的物体被推入   更高的世代,1或2   垃圾收集器工作更多   经常在下一代   而不是更高的那些。

     

首次创建对象时,它是   投入生成0.当   第0代被填满,垃圾   收集器被调用。那个对象   幸存下来的垃圾收集   第一代被提拔到了   下一代更高代,第1代。   垃圾中存活的物体   第1代的收集是   晋升到下一个和最高的   一代,二代。这   算法有效地工作   垃圾收集对象,因为它   很快请注意,第2代是   最高的一代   由垃圾收集器支持。

Garbage Collection in .NET

  

世代

     

内存分配时   托管堆很快,GC本身   可能需要一些时间。考虑到这一点   已经进行了几次优化   提高性能。 GC   支持世代的概念,   基于这样的假设   一个对象在堆上的时间越长,   它可能会停留的时间越长   那里。分配对象时   它属于第0代的堆。   那个垃圾收集   对象幸存增加了它   生成1(目前最高   支持生成是2)。明显   搜索速度更快,而且   垃圾收集所有的子集   堆上的对象,所以GC有   只收集一代的选择   0,1或2个对象(或其他任何东西   它选择的组合,直到它有   足够的记忆)。即使在   只收集GC的年轻物体   还可以确定旧对象是否具有   引用新对象以确保   它不会无意中忽略   使用中的物体。

答案 1 :(得分:20)

“Pro C#2008”中有一个很好的描述:

  1. 第0代标识新创建的对象,该对象从未被标记为集合
  2. 第1代标识一个在GC中存活的对象(标记为收集但由于堆空间足够而未被删除)
  3. 第2代识别出一个在GC的多次扫描中幸存下来的对象。

答案 2 :(得分:12)

我的第一篇博客, Generations of Garbage Allocation,回答你的问题:

  

CLR的垃圾收集器(GC)是一代垃圾收集器,也称为ephermal垃圾收集器。

     

它有三代:

     

第0代:

     

它包含所有新构造的对象,它们从未被GC检查过。

     

第1代:

     

CLR在初始化时为第0代选择以kb为单位的预算大小。如果创建对象导致第0代超过其预算,则启动垃圾收集。在第0代中未收集的对象将移至第1代,第0代将被清空。   假设第0代的预算等于5个对象的大小。因此,在创建对象6之前,第0代将如下所示:

     

enter image description here

     

在创建对象6之后,垃圾分配开始,它会释放垃圾对象1,3和5,并在第1代中相互移动2和4。

     

enter image description here

     

第一代的预算大小也由CLR在初始化时选择。创建对象11会导致GC再次启动,这可能会将更多对象移动到第1代。

     

enter image description here

     

垃圾收集忽略第1代,直到达到垃圾收集的预算大小,从而提高GC的性能。

     

第2代:

     

在第0代0集合中,第1代可能超过它的预算限制,导致GC从两代收集垃圾。在这种情况下,第1代幸存者被提升为第2代,第0代幸存者被提升为第1代,第0代则为空。

     

假设分配对象21导致垃圾收集和第1代预算已达到。   enter image description here

     

所以堆将如下所示,第1代中幸存的对象被提升为第2代。

     

enter image description here

     

因此,生成GC基本上假设较新的对象有更多的概率被收集。

     

我们知道CLR会为所有三代选择预算,但它可以修改它们,因为GC是一个自我调整的收集器。如果GC在收集第0代后发现存在的对象很少,则可能决定减少第0代的预算,从而减少工作量。另一方面,如果GC收集第0代并且发现存在大量幸存对象,则垃圾收集中不会回收大量内存。在这种情况下,垃圾收集器将增加第0代的预算。 GC还相应地修改了第1代和第2代的预算。