Server, Workstation and Concurrent GC

One common question I see asked is the differences between server and workstation GC, and how Concurrent GC fits in.

Server GC is only available on multi-proc machines. It creates one GC heap (and thus one GC thread) for each processor, which are collected in parallel. This GC mode maximizes throughput (number of requests per second) and shows good scalability (performance really shines with 4 or more processors).

Workstation is the default GC mode. On a single-proc machine, it’s the only option.

Concurrent GC is used in Workstation mode on a multi-proc machine. It performs full collections (generation 2) concurrently with the running program, minimizing the pause time. This mode is particularly useful for applications with graphical user interfaces or applications where responsiveness is essential.

How do I choose a GC mode?

In v1.0 and v1.1 (pre-SP1), server mode can only be used if the runtime is hosted in an unmanaged application (for example, ASP.NET hosts web applications in server mode). Concurrent mode can be specified in the machine or application’s configuration file. If neither is chosen, or if on a single-proc machine, Workstation is the default.

Note: Server mode automatically disables Concurrent GC.

To set GC mode to Concurrent:

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

To set GC mode to Server (unmanaged C++):

HRESULT CorBindToRuntimeEx( LPWSTR pwszVersion,
  LPWSTR pwszBuildFlavor, // use “svr” for server mode,
  // “wks” or NULL for workstation
  DWORD flags,
  REFCLSID rclsid,
  REFIID riid,
  LPVOID* ppv );

One of the most popular feature requests was the ability to specify the GC mode in a non-hosted managed application. In Whidbey (v2.0) and v1.1 SP1, we added a new feature that allows you to specify the GC mode in the application’s config file:

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

Note: if the application is hosted, the host’s GC mode overrides the config file.

How do I tell which GC mode my app is using?

In v1.0 and v1.1 of the CLR, the GC was contained in two core DLLs: mscorwks.dll and mscorsvr.dll. If the application is running in server mode, then mscorsvr.dll is loaded, otherwise, mscorwks.dll is loaded. The only way to tell which is loaded is to look at the list of running processes.

Remember, on a single proc-machine, it’s Workstation. On a multi-proc where throughput is important, use Server. If there's user interaction, choose Concurrent.

Edit: Minor corrections.

Edit: Fixed case in XML tags. Thanks Tyler!