#939 – Not All Objects on Heap Are Promoted to Next GC Generation

Objects on the managed heap are grouped into generations by the garbage collector (GC), as follows:

  • Generation 0 – Objects that have been created since the last GC pass  (newest objects)
  • Generation 1 – Objects that have survived one pass of the GC
  • Generation 2 – All other objects  (oldest objects)

Objects are only promoted to the next generation if the generation that they are currently located in is examined and collected during a garbage collection pass.

This means:

  • Since the GC always examines Gen 0 during any GC pass, Gen 0 objects that survive a garbage collection are always promoted to Gen 1.
  • Objects in Gen 1 are only promoted to Gen 2 if Gen 1 is examined and collected during a GC pass and the object survives.  The GC will very often do only a Gen 0 pass during collection.  When the GC only examines and collects Gen 0, Gen 1 objects are not examined and therefore not promoted to Gen 2.
Advertisement

#938 – Finding Out What GC Generation an Object Is In

The garbage collector (GC) groups objects into generations to avoid having to examine and collect all objects in memory whenever a garbage collection is done.

For debugging purposes, it’s sometimes useful to know which generation an object currently belongs to.  You can get this information using the GC.GetGeneration method, as shown below.

            Dog bob = new Dog("Bob", 5);
            Console.WriteLine(string.Format("Bob is in generation {0}", GC.GetGeneration(bob)));

            GC.Collect();
            Console.WriteLine(string.Format("Bob is in generation {0}", GC.GetGeneration(bob)));

            GC.Collect();
            Console.WriteLine(string.Format("Bob is in generation {0}", GC.GetGeneration(bob)));

In the example above, the “Bob” Dog object starts out in generation 0. After we do the first garbage collection, it’s promoted to generation 1 and after the 2nd collection, it’s promoted to generation 2.
938-001

#936 – Visualizing Garbage Collection Generations

The garbage collection groups objects on the managed heap into generations.  This improves the performance of the garbage collector (GC), since it typically collects objects in Generation 0 (newest), only moving to older generations if necessary.

Below is an example of this.  To start with, we have an empty managed heap (no objects).  The entire heap is considered Generation 0, since we haven’t yet done a garbage collection.

936-001

We now allocate three Dog objects on the heap.  They are allocated in the first available space within Gen 0.

936-002

We now set the yourDog reference to null, so that Jack is no longer referenced.  Before garbage collection, the heap looks like this:

936-003

Assume that a GC pass runs now and collects objects in Gen 0 (the only generation available).  Memory for Jack is released, everything in Gen 0 is compacted, and whatever remains is marked as Gen 1.  Gen 0 now starts again at the free space pointer.

936-004

Assume that we run for a while and allocate a couple more Dog objects–Lassie and Rin Tin Tin.  Then assume that the reference to Lassie is removed and that the reference to Ruby is also removed.  Before collection, the heap looks as follows.  Notice that there are unreachable objects in both Gen 0 and Gen 1.

936-005

Assume that a garbage collection now runs and collects only Gen 0.  Memory for Lassie is reclaimed, Gen 0 is compacted and and its objects are promoted to Gen 1.  The existing Gen 1, however, is not collected and its objects remain in Gen 1.

936-008

Finally, let’s assume that the garbage collection runs one more time.  It begins with Gen 0, but there is nothing to collect.  Let’s assume that there are high memory demands that cause the GC to decide to also collect Gen 1.  It can now release memory for Ruby and then compacts Gen 1 and promotes its surviving objects to Gen 2.

936-007

#933 – The Garbage Collector Groups Objects into Generations

Referenced-typed objects in an application have different lifetimes.  The application will use some objects as long as the application is running.  Others are referenced only during execution of a single method.

If the garbage collector always examined every object whenever it did a garbage collection pass, it would spend a lot of time reexamining longer-living objects that can’t yet be garbage collected.  The garbage collector can perform more efficiently by looking at only a subset of all objects during each pass.  It does this by grouping objects into generations:

  • Generation 0 – Objects that have been created since the last GC pass  (newest objects)
  • Generation 1 – Objects that have survived one pass of the GC
  • Generation 2 – All other objects  (oldest objects)

The garbage collector examines and collect objects in generation 0, moving to higher generations only if it needs additional memory.

Objects are promoted to the next generation only if a GC pass is done on the generation in which they are located.