CLR 4.0: New Enhancements in the Garbage Collection

Note: This blog post transferred from my OLD BLOG and was originally posted in 2008.


The current Garbage Collection does pretty good job in reclaiming the memory of Gen 0 and Gen 1, those Generation’s objects live in ephemeral segments which is very small and GC reclaims their memory very fast, on the contrary most of Gen 2 objects live in other large segments which make Gen 2 large objects collection slower than other collections.

The GC team actually made great improvements in collection algorithms on both the server and the workstation to make it faster and reduce latency.

Enhancements in Server Garbage Collection

The current server GC is very efficient in terms of maximizing the overall throughput; this because GC’s Gen 2 actually pauses all the current running managed code on the server while it runs. And It turns out that this makes the GC as fast as all of us need “BUT” the cost is generating those long pauses on the server managed code execution, and increasing the latency of course!

What the CLR team did in v4.0 is they allow you to be notified before Gen 2 collection (LOH collection or Large Object Heap Collection) happens. You might ask how this could help me in reducing those latency on my server? And in fact there are good news and bad news; the good news is yes this will help you to reduce the latency and reduce the long pauses on your server, and the bad news is this will not help everyone in reality it will help you if you only uses some Load Balancing techniques.

What now CLR offering is a notification model you can use to know when GC starts Gen 2 collection on the current server, so you can switch the user traffic through your load balancer to another application server and then start Gen 2 collection for the old traffic on the first application server; your user will not feel that same latency and long pauses as before.


I’m gona walk you through sample code to learn you how to benefit from this new enhancement in your server applications. 

   1: public class Program
   2: {
   3:     public static void Main(string[] args)
   4:     {
   5:         try
   6:         {
   7:             // Register on the FullGCNotification service
   8:             // Set the Maximum generation Threashold and 
   9:             // the large object heap threshold
  10:             GC.RegisterForFullGCNotification(10, 10);
  12:             // wait for the notification to happen on a new thread
  13:             Thread fullGCThread = new Thread(new ThreadStart(WaitForFullGC));
  14:             fullGCThread.Start();
  15:         }
  16:         catch (InvalidOperationException ex)
  17:         {
  18:             Console.WriteLine(ex.Message); 
  19:         }
  20:     }
  21:     public static void WaitForFullGC()
  22:     {
  23:         while (true)
  24:         {
  25:             // This is a blocking call, once it returns with succeed
  26:             // status, this means that Gen 2 collection is about to happen
  27:             GCNotificationStatus status = GC.WaitForFullGCApproach();
  29:             if (status == GCNotificationStatus.Succeeded)
  30:             {
  31:                 // now you call your custom procedure to switch
  32:                 // the trafic to another server
  33:                 OnFullGCApproachNotify();
  34:             }
  36:             // Now you are waiting for  GC to complete Gen 2 collection
  37:             status = GC.WaitForFullGCComplete();
  38:             // once it finish you call your custom procedure to switch back
  39:             // the traffic to your first server
  40:             if (status == GCNotificationStatus.Succeeded)
  41:             {
  42:                 OnFullGCCompleteNotify();
  43:             }
  45:         }
  46:     }
  48:     private static void OnFullGCApproachNotify()
  49:     {
  50:         // 1. Direct the new traffic away from this server
  51:         // 2. Wait for the old traffic to finish
  52:         // 3. Call GC.Collect, and this is the interesting part because
  53:         // Microsoft always tells you not to call GC.Collect yourself.
  54:         // but here you will need to do that because there are no more traffic
  55:         // redirected to this server, so you might wait forever before the GC starts
  56:         // so you need to start the GC.Collect() yourself
  57:         GC.Collect();
  58:     }
  59: }
Enhancements in Workstation Garbage Collection
Today’s CLR have a Concurrent Collection algorithm for workstation’s GC, this algorithm can do most of Gen 2 objects collection without pausing the running managed code too much at least not as much as on GC’s Server algorithms.
So the problem occur when ephemeral segments fills up during GC is busy making Gen 2 collection on other segments then a new objects allocated from ephemeral segments that’s when the pauses happen on the workstation and the user feels the latency; Concurrent Collection Algorithm can’t run Gen 0 and Gen 1 at the same time as Gen 2 is occurring.
New in CLR 4.0 a new collection algorithm used for Workstation’s GC collection instead of the Concurrent Collection Algorithm, this new algorithm is called Background Collection Algorithm, one key thing about this new Background Algorithm is it can do Gen 0 and Gen 1 at the same time Gen 2 is occurring; and in that way you will not see long pauses in your client application as before only in very unusual circumstances.
In the upper chart you can see a statistical comparison between the Old Concurrent Algorithm and the Background Algorithm performance. As you ca see at the start of the application in both of the algorithms there is one pause but it takes half the time in the Background algorithm, one the application continue working in the case of Concurrent GC  there are multiple long pauses, on the contrary in the Background GC you se far a few longer pauses as before.
With new GC Notification Algorithm on server managed applications and new Background Collection Algorithm on Workstation managed applications; the CLR team leverage a new performance experiences with fewer long pauses and great latency.
Related Stuff:
  1. PDC 2008: PC49, Microsoft .NET Framework – CLR Futures (Video|PPTX).
  2. Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework (Jeffrey Richter).
Hope this Helps,


  1. […] Couple of years ago I blogged about a new Background GC in Workstation mode in CLR 4.0 the main idea is while executing Gen 2 collection, CLR checks at well defined points if Gen0/Gen1 has been requested, if true then Gen2 is paused until the lower collection runs to completion then it resumes. Read more about Background mode for Workstation GC. […]


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s