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

46 .net garbage-collection

我还没有了解垃圾收集的几代人,虽然我从谷歌找到了一些.你们中的一些人可以用简单的语言告诉我.

或者可以参考一个易于理解的链接!

Adr*_*der 53

了解.NET中的垃圾收集

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

首次创建对象时,将其置于第0代.当填充第0代时,将调用垃圾收集器.在第一代垃圾收集中存活的对象被提升到下一代更高代,第1代.在第1代中存活垃圾收集的对象被提升到下一代和最高代,第2代.该算法有效地用于垃圾对象的集合,因为它很快.请注意,第2代是垃圾收集器支持的最高代.

.NET中的垃圾收集

虽然托管堆上的内存分配很快,但GC本身可能需要一些时间.考虑到这一点,已经进行了一些优化以提高性能.GC支持代的概念,基于这样的假设:对象在堆上的时间越长,它可能在那里停留的时间越长.当在堆上分配对象时,它属于第0代.对象存活的每个垃圾收集使其生成增加1(当前支持的最高代是2).显然,搜索更快,并且垃圾收集堆上所有对象的子集,因此GC可以选择仅收集0,1或2个对象(或者它选择的任何组合,直到它有足够的内存).即使在仅收集较年轻的对象时,GC也可以确定旧对象是否具有对新对象的引用,以确保它不会无意中忽略正在使用的对象.


duf*_*ymo 20

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

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

  • 你写道:“第 1 代标识了一个在 GC 中幸存下来的对象(标记为收集但没有删除,因为有足够的堆空间)” - 你的意思是:第 1 代标识了一个在 GC 中幸存下来的对象(没有被删除)当垃圾收集正在运行时,因为它仍然有对它的引用)? (5认同)

Dee*_*hra 12

我的第一篇博客回答了你的问题: 垃圾分配的世代

添加有关链接的信息:

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

它有三代:

第0代: 它包含所有新构造的对象,这些对象从未被GC检查过.

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

在此输入图像描述

在创建对象6之后,开始垃圾分配,其在第1代中解除分配垃圾对象1,3和5并且移动彼此相邻的2和4.

在此输入图像描述

CLR在初始化时也选择第1代的预算大小.对象11的创建使GC再次启动,这可以将更多对象移动到第1代.

在此输入图像描述

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

第2代:

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

假设分配对象21导致垃圾收集和第1代预算已达到. 在此输入图像描述

所以堆看起来像下面的那样,第1代中幸存的对象被提升为第2代.

在此输入图像描述

所以基本上生成GC假设更新的对象有更多的概率收集.

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

  • 这是这里最清晰、最深入的答案:) (2认同)