4

What is the difference between large object heap and GC 3rd generation objects?

Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
Ravi Sharma
  • 116
  • 1
  • 7

1 Answers1

19

The LOH (Large Object Heap) is a single heap where large objects are allocated directly and stay there until they are collected. Objects are directly allocated into the LOH based on their size e.g. being equal or greater than 85000 bytes.

Generational objects are "small" objects that are allocated into the SOH (Small Object Heap) which is a single heap. Objects in the SOH have an associated generation which denotes how many collections they have survived up to the maximum generation e.g. 2. As the generation number starts at 0, an object in generation 2 could be described as 3rd generation as it has survived a minimum of 3 collections i.e. generations 0,1,2.

Generations helps to optimize garbage scanning. Long lived objects have their generation number increased as they survive collections, and generations with a higher number are scanned less frequently. This mechanism results in objects that are not short-lived being scanned less frequently and therefore unnecessarily. The generational scheme is applied to the SOH as it seen as a good optimization for a heap where there will be lots of objects.

Update

As far as I understand LOH objects are reported as being in the max generation, but I believe that this is just a default value. They are not actually in any generation i.e. generation 2 SOH objects and LOH objects are not in the same "list". However, as pointed out by @Henk, when performing a generation 2 collection, LOH objects are also collected at this time. So conceptually there is a relationship between generation 2 and the LOH. This is correct as of .Net 2.0:

See: Large Object Heap Uncovered

From a generation point of view, large objects belong to generation 2 because they are collected only when there is a generation 2 collection.

However, although the collection relationship is apparent, an example where it does not hold is generation compaction. When a generation is collected it may also be compacted. The LOH is not however compacted, so it cannot be said that everything that happens to generation 2 objects happens to the objects in the 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.");
}
Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
  • So the objects which are bigger than 85kb always go to LOH and not to SOH, thats the rule? – Ravi Sharma Feb 02 '11 at 14:24
  • I thought LOH objects also belong to a generation, not 100% sure. But while they are marked and sweeped the same, they are not compacted. – H H Feb 02 '11 at 14:26
  • And No generations are there in LOH? – Ravi Sharma Feb 02 '11 at 14:26
  • @Henk: Yes Henk i am also having the same confusion. – Ravi Sharma Feb 02 '11 at 14:29
  • @Henk As far as I am aware, they have a default generation but they don't actually belong to one i.e. `GC.GetGeneration(obj)` will always return `GC.MaxGeneration`. – Tim Lloyd Feb 02 '11 at 14:34
  • @Ravi Whether objects go into the LOH is based on at least size, but the rules are not made public and there is no API to derive these rules. One rule that is often spoken about though is objects larger than 85000 bytes (and that is not 85k). Again these rules are not discoverable via the API. I have updated my question a little. – Tim Lloyd Feb 02 '11 at 14:47
  • Thanks chibacity, nicely explained. – Ravi Sharma Feb 02 '11 at 15:24
  • You're cutting it awfully close in that test-case. – H H Feb 02 '11 at 21:26
  • And: "From a generation point of view, large objects belong to generation 2 ", see http://msdn.microsoft.com/en-us/magazine/cc534993.aspx – H H Feb 02 '11 at 21:27
  • @Henk My interpretation is that LOH objects are not actually in generation 2 as in there is a list of objects for generation 2 and both LOH and SOH objects are in it. Rather that it is a conceptual distinction. I see how it is cutting it fine - my update is not quite correct. I think that pointing out that LOH objects are not actually "in" gen 2 is correct and worth poting out. I'll update my answer when I'm next at a PC. Cheers. – Tim Lloyd Feb 02 '11 at 22:04
  • @Henk Fair point I have updated. I am still trying to emphasise the distinction of generation 2 SOH objects and LOH objects, as I think this answers the question better. I think to say they were in the *same* generation is a little confusing, although conceptually appropriate when talking about a gen 2 collection. – Tim Lloyd Feb 02 '11 at 22:23
  • This is an old post, but as of .NET 4.5.1 while LOH objects still do not get compacted when a 2nd generation compaction occurs by default, you can actually make this happen this by using `GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;` – Lexi Tramel Jun 24 '15 at 18:16