Welcome to MSDN Blogs Sign in | Join | Help

Maoni's WebLog

CLR Garbage Collector
So, what’s new in the CLR 4.0 GC?

PDC 2008 happened not long ago so I get to write another “what’s new in GC” blog entry. For quite a while now I’ve been working on a new concurrent GC that replaces the existing one. And this new concurrent GC is called “background GC”.

First of all let me apologize for having not written anything for so long. It’s been quite busy working on the new GC and other things.

Let me refresh your memory on concurrent GC. Concurrent GC has existed since CLR V1.0. For a blocking GC, ie, a non concurrent GC we always suspend managed threads, do the GC work then resume managed threads. Concurrent GC, on the other hand, runs concurrently with the managed threads to the following extend:

§  It allows you to allocate while a concurrent GC is in progress.

 

However you can only allocate so much – for small objects you can allocate at most up to end of the ephemeral segment. Remember if we don’t do an ephemeral GC, the total space occupied by ephemeral generations can be as big as a full segment allows so as soon as you reached the end of the segment you will need to wait for the concurrent GC to finish so managed threads that need to make small object allocations are suspended.

 

§  It still needs to stop managed threads a couple of times during a concurrent GC.

 

During a concurrent GC we need to suspend managed threads twice to do some phases of the GC. These phases could possibly take a while to finish.

 

We only do concurrent GCs for full GCs. A full GC can be either a concurrent GC or a blocking GC. Ephemeral GCs (ie, gen0 or gen1 GCs) are always blocking.

 

Concurrent GC is only available for workstation GC. In server GC we always do blocking GCs for any GCs.

Concurrent GC is done on a dedicated GC thread. This thread times out if no concurrent GC has happened for a while and gets recreated next time we need to do concurrent GC.

When the program activity (including making allocations and modifying references) is not really high and the heap is not very large concurrent GC works well – the latency caused by the GC is reasonable. But as people start writing larger applications with larger heaps that handle more stressful situations, the latency can be unacceptable.

Background GC is an evolution to concurrent GC. The significance of background GC is we can do ephemeral GCs while a background GC is in progress if needed. As with concurrent GC, background GC is also only applicable to full GCs and ephemeral GCs are always done as blocking GCs, and a background GC is also done on its dediated GC thread. The ephemeral GCs done while a background GC is in progress are called foreground GCs.

So when a background GC is in progress and you’ve allocated enough in gen0, we will trigger a gen0 GC (which may stay as a gen0 GC or get elevated as a gen1 GC depending on GC’s internal tuning). The background GC thread will check at frequent safe points (ie, when we can allow a foreground GC to happen) and see if there’s a request for a foreground GC. If so it will suspend itself and a foreground GC can happen. After this foreground GC is finished, the background GC thread and the user threads can resume their work.

Not only does this allow us to get rid of dead objects in young generations, it also lifts the restriction of having to stay in the ephemeral segment – if we need to expand the heap while a background GC is going on, we can do so in a gen1 GC.

We also made some performance improvement in background GC which does better at doing more things concurrently so the time we need to suspend managed threads is also shorter.

We are not offering background GC for server GC in V4.0. It’s under consideration – we recognize how important it is for server applications (which usually have much larger heaps than client apps) to benefit from smaller latency but the work did not fit in our V4.0 timeframe. For now for server applications, I would recommend you to look at the full GC notification feature we added in .NET 3.5 SP1. It’s explained here: http://msdn.microsoft.com/en-us/library/cc713687.aspx. Basically you register to get notified when a full GC is approaching and when it’s finished. This allows you to do software load balancing between different server instances – when a full GC is about to happen in one of the server instances, you can redirect new requests to other instances.

Posted: Wednesday, November 19, 2008 5:02 PM by maoni
Filed under: ,

Comments

gOODiDEA.NET said:

.NET Redirecting without the exceptions So, what’s new in the CLR 4.0 GC? Source Control for Visual

# November 24, 2008 8:18 PM

gOODiDEA said:

.NETRedirectingwithouttheexceptionsSo,what’snewintheCLR4.0GC?SourceControlforVisu...

# November 24, 2008 8:19 PM

wasthebest said:

This question regards what might be a bug in .NET Framework 1.1, but I think it applies here as it regards a multi-threaded app and the GC. After changing the system time (to speed up events,) some of my weak references are lost, although the original object is still alive. Why would this happen? Can changing the system time corrupt the GC?

# November 26, 2008 1:09 PM

wasthebest said:

Egg on face. My problem is clearly an application bug as I tracked down an inconsistency in what Target was being assigned. Sorry, I have a policy (from previous experience) to go to MS as a last resort, but you know how we programmers sometimes lose our senses.

Anyway, maybe I’m out of the times or uninformed here, but I would like to see the GC tell us ONE place where objects are still alive: for debugging purposes. The objects can be registered separately with the GC, and then every 3 seconds or so after it completes its cleaning, raise an event that provides this information. Each event handler should be given its own thread to avoid one event handler from unfairly blocking the others. Where objects are alive can be given in increments.

# November 27, 2008 2:49 PM

wasthebest said:

Never mind. I discovered the Remote Performance Monitor (http://blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using-the-net-cf-remote-performance-monitor.aspx) which basically provides what I had in mind, but in a more meaningful way.

# November 29, 2008 8:45 PM

Sam Gentile's Blog said:

First new and notable with the new Graffiti blog. WCF/Cloud Services Aaron has his latest in his series of WCF screencasts , this time showing how to host WCF services within traditional Windows services Aaron also has a geekSpeak webcast on Cloud Services

# December 3, 2008 9:56 AM

Nomad said:

We have large network server app with gcServer turned on. GC threads are using about 5-10% of CPU time but it runs rather smoothly. Blocking delays are almost unnoticeable.

Could I benefit from switching to .Net 4.0 and background GC in that case?

# March 20, 2009 7:46 AM

maoni said:

Nomad, if the latency is not an issue, I would recommand to stay with gcServer 'cause it offers great performance benefit with mulitple GC threads collecting the heap for you.

# March 27, 2009 6:59 PM

Dusan said:

Can you please somehow *push* your GC to be used in/for Microsoft ECMA/JavaScript ? Particularly inside IE8.

Regards: Dusan

# April 24, 2009 9:02 AM

Metta said:

Hi Maoni

This is a bit unrelated to the topic, but I see an application using server GC where "% time in GC" perf counter keeps stuck at the same value for minutes after running for a bit and all other processing seems to stop. CPU spins at 100% on one processor. This is triggered by a Gen 0 collection, so I wonder if this is a GC related issue or not.

# May 25, 2009 4:49 PM

If broken it is, fix it you should said:

Yesterday I found this really nice Channel 9 interview with Maoni Stevens (Dev Owner of the CLR GC) and

# May 29, 2009 7:23 AM

Alexandre Eduardo said:

Quotting:

"We are not offering background GC for server GC in V4.0. It’s under consideration – we recognize how important it is for server applications (which usually have much larger heaps than client apps) to benefit from smaller latency but the work did not fit in our V4.0 timeframe. For now for server applications, I would recommend you to look at the full GC notification feature we added in .NET 3.5 SP1. It’s explained here: http://msdn.microsoft.com/en-us/library/cc713687.aspx. Basically you register to get notified when a full GC is approaching and when it’s finished. This allows you to do software load balancing between different server instances – when a full GC is about to happen in one of the server instances, you can redirect new requests to other instances."

Maoni,

First of all, congrats! Your blog is really interesting. Every time I look at it, I find some interesting news.

Concerning to the server GC, it would be great to have such behavior (background gc) within.

Unfortunatelly, for real-time/time-critical applications (on wich every microsecond is really really precious), the cost of changing to another process after a GC notification is too expensive to be considered. More than that, an extra overhead should be added to the application in order to synchronize both process with the same state information (even shared memory has a little cost).

Hugs!

Alexandre

# June 19, 2009 1:49 PM

John said:

Are there any plans to make the ephemeral heap size configurable?  

# June 22, 2009 1:35 PM

Joe said:

I just wanted to say this is a big step in the right direction for allowing .net to meet the requirements of the software I work on.  I am extremely excited to see the Server mode support background GC.  Any idea when this could be seen in any betas?

# June 23, 2009 9:18 AM

Sohel Rana said:

Do you have any plan to include server background GC in CLR soon?

# June 24, 2009 3:23 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker