【发布时间】:2011-01-16 11:39:39
【问题描述】:
我不明白垃圾收集上下文中的“世代”是什么。谁能简单的解释一下?
【问题讨论】:
我不明白垃圾收集上下文中的“世代”是什么。谁能简单的解释一下?
【问题讨论】:
来自Understanding Garbage Collection in .NET
世代
分代垃圾收集器 多收集短命的对象 经常比寿命更长的。 短期对象存储在 第一代,0代。 寿命更长的物体被推入 更高的世代,1 或 2。 垃圾收集器工作更多 经常在低代 比更高的。
当一个对象第一次被创建时,它是 放入第 0 代。当 第0代被填满,垃圾 收集器被调用。那些对象 在垃圾收集中幸存下来 第一代被提升到 下一代更高一代,第 1 代。 在垃圾中幸存的对象 第 1 代的收集是 晋升到下一个和最高的 一代,2代。这 算法有效地适用于 对象的垃圾收集,因为它 很快。请注意,第 2 代是 最高的一代 由垃圾收集器支持。
世代
内存分配时 托管堆很快,GC本身 可能需要一些时间。考虑到这一点 进行了多项优化 以提高性能。 GC 支持世代的概念, 基于这样的假设 一个对象在堆上的时间更长, 它可能会停留的时间越长 那里。当一个对象被分配到 它属于第 0 代的堆。 每个垃圾收集器 对象生存增加其 1代(目前最高 支持的世代是 2)。明显地 搜索速度更快,并且 垃圾收集所有的子集 堆上的对象,所以 GC 有 仅收集一代的选项 0、1 或 2 个对象(或其他 它选择的组合,直到它有 足够的内存)。即使在 GC 只收集较年轻的对象 还可以确定旧对象是否有 对新对象的引用以确保 它不会无意中忽略 正在使用的对象。
【讨论】:
“Pro C# 2008”中有一个很好的描述:
【讨论】:
我的博客, Generations of Garbage Collection,回答你的问题:
CLR 的垃圾收集器 (GC) 是一种分代垃圾收集器,也称为临时垃圾收集器。
它分为三代:
0代:
它包含所有新构建的对象,这些对象从未被 GC 检查过。
第一代:
CLR 在初始化时为第 0 代选择一个以 kb 为单位的预算大小。如果对象的创建导致第 0 代超出其预算,则开始垃圾收集。第 0 代中未收集的对象被移到第 1 代,第 0 代被清空。 假设第 0 代的预算等于 5 个对象的大小。因此,在创建对象 6 之前,第 0 代将如下所示:
在创建对象 6 后,垃圾分配开始,这将释放垃圾对象 1、3 和 5,并在第 1 代中将 2 和 4 移动到彼此相邻的位置。
第 1 代的预算大小也是由 CLR 在初始化时选择的。对象 11 的创建会导致 GC 重新开始,这可能会将更多对象移动到第 1 代。
第 1 代被忽略用于垃圾收集,直到它达到垃圾收集的预算大小,这提高了 GC 的性能。
第二代:
在多次第 0 代收集中,第 1 代可能会超出其预算限制,从而导致 GC 从两代收集垃圾。在这种情况下,第 1 代幸存者被提升到第 2 代,第 0 代幸存者被提升到第 1 代,第 0 代为空。
所以堆看起来像下面这样,在第 1 代中幸存的对象被提升到第 2 代。
所以基本上 Generation GC 假定较新的对象更有可能被收集。
我们知道 CLR 会为所有三代选择预算,但它可以修改它们,因为 GC 是一个自我调整的收集器。如果 GC 在收集到第 0 代后发现存活的对象很少,它可能会决定减少第 0 代的预算,从而完成更少的工作。另一方面,如果 GC 收集第 0 代并看到有很多幸存对象,则在垃圾收集中没有回收很多内存。在这种情况下,垃圾收集器将增加第 0 代的预算。 GC 也会相应地修改第 1 代和第 2 代的预算。
【讨论】: