垃圾回收中的几代是什么?

61

在垃圾回收的上下文中,我不明白"generations"是什么意思。 能否简单解释一下?

3个回答

64

来自.NET中的垃圾回收机制

代垃圾收集器更频繁地收集短寿命对象而不是长寿命对象。短寿命对象存储在第一代,即0代中。长寿命对象被推入较高的1代或2代。垃圾收集器在低代中的工作频率比高代中更高。

当一个对象首次创建时,它被放置在0代中。当0代填满时,垃圾收集器被调用。在第一代中经过垃圾回收后幸存的对象将被提升到下一个更高的代,即1代。在1代中经过垃圾回收后幸存的对象将被提升到最高的2代。这个算法对于对象的垃圾回收非常有效,因为它很快。请注意,2代是垃圾收集器支持的最高代。

.NET中的垃圾回收机制

代际

虽然托管堆上的内存分配很快,但GC本身可能需要一些时间。考虑到这一点,进行了几项优化以提高性能。GC支持代际的概念,基于这样的假设:对象在堆上存在的时间越长,它就可能在那里停留的时间也越长。当对象在堆上分配时,它属于第0代。每次垃圾回收中,对象幸存下来都会将其代数增加1(目前支持的最高代数为2)。显然,搜索和垃圾回收堆上所有对象的子集速度更快,因此GC有选项仅收集第0、1或2代对象(或任何组合,直到具有足够的内存)。即使只收集年轻对象,GC也可以确定旧对象是否引用新对象,以确保不会无意中忽略正在使用的对象。


显然,仅搜索和垃圾回收堆中所有对象的子集会更快...我认为这个短语是误导性的。据我所知,GC不能仅搜索单个代 - 无论它们属于哪个代,它都必须从根开始,并每次构建完整图形。它也不能跳过将幸存对象提升到下一代。据我所知,它真正可以跳过的唯一事情是较旧代的压缩?而主要优点是所有非垃圾都被提升并复制到第0代空间之外,因此可以一次性擦除? - Ivan Koshelev

29

在《Pro C# 2008》中有一个很好的描述:

  1. 第0代标识一个新创建的对象,它从未被标记为需要回收
  2. 第1代标识一个已经经历过垃圾回收的对象(已经被标记为需要回收,但由于堆空间充足而没有被移除)
  3. 第2代标识一个已经经历过多次垃圾回收的对象。

7
你写道:“一代标识一个在垃圾回收中幸存下来的对象(被标记为待清除但由于堆空间充足而未被移除)”,难道你的意思不是:一代标识一个在垃圾回收中幸存下来的对象(因为仍有引用指向它,所以在垃圾回收运行时没有被移除)吗? - BornToCode
@BornToCode 不,微软的实现似乎使用了一种预算机制,其中Gen1被赋予了建议使用的内存量。只有当超过此数量时,它才会起作用。这减少了GC实际操作的次数,从而提高了性能。但是,该空间并不等于最大可用堆空间。它介于两者之间。 - AlexGeorg

29

我的博客,垃圾回收的世代, 回答了你的问题:

CLR的垃圾回收器(GC)是一种世代垃圾回收器,也称为暂时性垃圾回收器。

它有三个世代:

第0代:

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

第1代:

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

enter image description here

创建对象6后,垃圾分配开始,释放垃圾对象1、3和5,并将2和4相邻地移动到第一代。

enter image description here

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

enter image description here

Generation 1在垃圾回收达到其预算大小之前被忽略,这可以提高GC的性能。
第二代:
在几次第一代集合之后,第一代可能超过其预算限制,导致GC从两代中收集垃圾。在这种情况下,第一代幸存者将晋升为第二代,第零代幸存者将晋升为第一代,第零代为空。
假设分配对象21导致垃圾回收并且第一代预算已经达到。enter image description here 因此,堆看起来像下面这样,第一代中幸存的对象晋升为第二代。

enter image description here

基本上,Generation GC 假设新对象更有可能被收集。
我们知道CLR为所有三代选择预算,但它可以修改它们,因为GC是一种自适应的收集器。如果GC在收集第0代后发现存活对象很少,它可能会决定减少第0代的预算,以减少工作量。另一方面,如果GC收集第0代并发现有很多存活对象,则垃圾回收中回收的内存不多。在这种情况下,垃圾回收器将增加第0代的预算。GC还相应地修改第1代和第2代的预算。

2
这是这里最清晰、最深入的答案 :) - AlexGeorg

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