.NET, CLR, GarbageCollection

Server vs Workstation vs Background vs Concurrent GC collection

I was reading a lot on Garbage Collection in .NET recently, as I was researching an memory leak in one of my projects and got carried away reading more and more MSDN articles. To my surprise there was a lot of new development in the area since last time I went geeky on the subject. So let me sum them up for the sake of future reference as maybe someone else will find them useful as well. You can find a good overview of current state of GC in CLR under in this MSDN article, so feel free to start there.

Workstation vs Server

There are actually two different modes of garbage collection, which you can control using gcServer tag in the runtime configuration part of your config file. Workstation Garbage Collection is set by default also it’s always used on a single processor machine even if you set the gcServer=”true”.

<configuration>
   <runtime>
      <gcServer enabled="true|false"/>
   </runtime>
</configuration>

those modes are actually pretty old, gcServer tag was introduced in .NET 2.0 and thus the second version of CLR. Key difference is that there are more then 1 thread performing a GC in Server mode and all of them run on THREAD_PRIORITY_HIGHEST priority level. There is a thread dedicated to GC and a separate heap (both normal and large object) for each CPU and all of them are collected at the same time. The idea here is that try to make a collection as quick as possible, using multiple thread operating at high priority, but it means all user threads need to paused until it’s ready. This is usually more suitable for server applications that most often value high throughput over responsiveness, which is not the case of traditional desktop apps. Server mode can also be quite resource consuming, as each CLR process will now have N GC dedicated threads, where N is number of processors.

Concurrent vs Background
Now besides Server vs Workstation, there are Concurrent and Background operation modes. Both of them allow a second generation to be collected by a dedicated thread without pausing all user threads. Generation 0 and 1 require pausing all user threads, but they are always the fastest. This of course increases the level of responsiveness an application can deliver. The actual modes vary and may also depend on Server vs Workstation type of GC, I’ll get into the details in next section. As it can get a bit more confusing, you can find all possible combinations below:

Workstation garbage collection can be:

  • Concurrent
  • Background
  • Non-concurrent

while options for Server garbage collection are as follows:

  • Background
  • Non-concurrent

Concurrent mode
This is a default mode for Workstation GC and will provide a dedicated thread performing GC, even on multiprocessor machines. You can turn it off using gcConcurrent tag.

<configuration>
   <runtime>
      <gcConcurrent enabled="true|false"/>
   </runtime>
</configuration>

This mode offers much shorter user threads pauses as the most time consuming Gen2 collection is done concurrently, on the cost of limited allocation capabilities during concurrent GC. While Gen2 collection takes place, other threads can only allocate up to the limit of current ephemeral segment, as it’s impossible to allocate new memory segment. If your process runs out of place in current segment, all threads will have to be paused anyway and wait for concurrent collection to finish. This is because Gen0 and Gen1 collections cannot be performed while concurrent GC is still in progress. Concurrent GC also has a slightly higher memory requirements.

Background mode
There is a new Background mode introduced in .NET 4.0 , that follows similar idea as Concurrent mode, but is supposed to be an improvement over it and by default is turned on, as it’s supposed to replace Concurrent mode. It’s also available for both Workstation and Server modes, while Concurrent was only available for Workstation. The big improvement being that Background mode can actually perform Gen0 and Gen1 collections while simultaneously performing Gen2. Those gen0,gen1 collections are now called foreground collections. Again only second generation collection is performed by separate thread while user threads are running, foreground collections require pausing all user threads. Also foreground collection requires a pause in background collection, so those to interact with each other through a various safe points. Background collection is available in Server GC and starting with .NET 4.5 is the default mode. The main difference between Server and Workstation Background mode is number of threads performing background GC. In Workstation it’s always a single thread, while in Server GC there will be a dedicated thread per CPU.

Standard

2 thoughts on “Server vs Workstation vs Background vs Concurrent GC collection

Leave a comment