大对象堆和 GC 第三代对象有什么区别?
1 回答
LOH (Large Object Heap) 是一个单一的堆,其中大对象被直接分配并保留在那里直到它们被收集。对象根据它们的大小直接分配到 LOH 中,例如等于或大于 85000 字节。
分代对象是分配到 SOH(小对象堆)中的“小”对象,它是单个堆。SOH 中的对象有一个关联的世代,表示它们在最大世代(例如 2)之前存活了多少个集合。由于世代数从 0 开始,第 2 代中的对象可以被描述为第 3 代,因为它至少存活了3 个集合,即第 0、1、2 代。
Generations 有助于优化垃圾扫描。长寿命对象的世代数随着它们在集合中的存活而增加,并且具有较高数量的世代被扫描的频率较低。这种机制会导致对非短命对象的扫描频率降低,因此是不必要的。分代方案适用于 SOH,因为它被视为对存在大量对象的堆的良好优化。
更新
据我了解,LOH 对象被报告为最大代,但我相信这只是一个默认值。它们实际上不在任何一代中,即第 2 代 SOH 对象和 LOH 对象不在同一个“列表”中。但是,正如@Henk 所指出的,在执行第 2 代收集时,此时也会收集 LOH 对象。所以从概念上讲,第 2 代和 LOH 之间存在关系。从 .Net 2.0 开始,这是正确的:
请参阅:发现大对象堆
从代的角度来看,大对象属于第 2 代,因为它们只有在有第 2 代收集时才会被收集。
然而,虽然集合关系是显而易见的,但它不成立的一个例子是生成压缩。当一代被收集时,它也可能被压缩。然而,LOH 没有被压缩,因此不能说发生在第 2 代对象上的所有事情都会发生在 LOH 中的对象上。
[Test]
public void large_object_heap_objects_are_reported_as_max_generation()
{
int[] bling = new int[85000 / 4];
int maxGen = GC.MaxGeneration;
int objectGen = GC.GetGeneration(bling);
Assert.AreEqual(maxGen, objectGen, "Large object is at max generation.");
}