#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.

#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.


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


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


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.


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.


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.


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.


#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.

#928 – How Objects Are Removed from the Managed Heap

The Garbage Collector (GC) manages the portion of virtual memory known as the managed heap, where referenced-typed objects are stored.  When an object is no longer referenced, it is destroyed and its memory made available for other objects.

More specifically:

  • The GC runs when available physical memory is low or when the amount of memory allocated on the heap passes some threshold
  • The GC follows all references to build a list of “reachable” objects
  • For all objects that are no longer reachable
    • If the object has a finalizer, it is marked for finalization (but not collected during this pass of the GC)
    • If the object doesn’t have a finalizer, it is marked for collection
  • Objects not marked for collection are compacted–moved to the start of the heap
  • References to moved objects are updated
  • The pointer to the end of the heap is updated (where new objects are allocated)

#926 – How Memory Is Allocated for Objects on the Managed Heap

When your applications starts up, the Garbage Collector (GC) allocates some virtual memory to use as a managed heap.  It creates a pointer to the next available free space in the managed heap, which defaults to point to the beginning of the (empty) heap.

When you use the new operator to create a new reference-typed object, the Garbage Collector allocates space on the managed heap for your object as follows:

  • It uses the pointer to the next available space on the heap to determine where to store your object
  • It advances the next available free space pointer, based on the size of your object
  • It zeroes out memory for the new object
  • It passes back a pointer to the new object, which is then stored in the reference-typed variable that refers to your object
  • The object’s constructor executes, to initialize data members within the object


#199 – You Can’t Explicitly Delete Heap-Based Objects

You create a new instance of a reference type by using the new operator and declaring a reference to the new object.  Memory for the object is allocated on the heap and the reference to the object is stored on the stack.

The object itself is able to be destroyed, i.e. its memory freed, when there are no longer any variables that reference it.  This is done automatically by the Garbage Collector (GC) in .NET.

Unlike with C++, you cannot explicitly delete a heap-based object and free its memory.  Only the Garbage Collector can release the memory for the object.  The Garbage Collector will not actually destroy the object unless a) there are no longer any references to the object and b) the CLR invokes the Garbage Collector because it needs memory.