.NET Garbage Collector is a very effective, high-speed allocation method with exceptional use of memory, and limited long-term fragmentation problems, however it is possible to do things that will give you reduced performance and so knowing how garbage collection works can be really important. I do a lot of development at the business layer these days and so I tend not to have to worry about how .NET is cleaning up after my work outside of ASP.NET Application Pools, most of the heavy lifting (for me) is generally done at another layer.
Simplified GC Generation Model
Objects are processed based on the following rules:
- Generation 0: This is the youngest generation and contains short-lived objects that have never been marked for allocation. An example of a short-lived object is a temporary variable. Garbage collection occurs most frequently in this generation.
- Generation 1: This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects. These objects have survived a garbage collection, that is to say they have been marked for collection but never removed.
- Generation 2: This generation contains long-lived objects. An example of a long-lived object is an object in a server application that contains static data that is live for the duration of the process. These objects have survived more than one sweep of the garbage collection.
Collection, prior to .NET 4 was based on a technique referred to as a Concurrent Garbage Collection. Under this original model collection takes place for any generation 0 and generation 1 objects. During this time active threads within the current process are suspended, this ensures that active threads do not access the heap during clean up, once the collection is completed the active threads resume. In theory that suspension time is very low, however, depending on your application “low” could mean a lot of things (I can already here our non-managed associates crying into their keyboards).
Background Garbage Collection (.NET 4.0)
.NET 4 has been around for a while now so I was actually surprised to learn that garbage collection had seen some improvements. First of all .NET 4.0 has improved the way in which it deals with thread suspensions when cleaning up the managed heap. In effect when dealing with with both generation 0/1 and generation 2 clean up simultaneously, the collections for the generation 0/1 can occur on a dedicated background thread. Together with reducing the overall clean up time, there is a marked improvement in the predictability and length of the GC stop time, this is extremely important for real-time systems.
In theory everyone is supposed to benefit from these recent improvements but I cannot help but think that there must be a couple of use cases where you will have to break open the Profiling tool and unleash the Performance Counters. Lets all take a deep breath and take a look at those memory dumps.