Performance Zone is brought to you in partnership with:

Sasha Goldshtein is a Senior Consultant for Sela Group, an Israeli company specializing in training, consulting and outsourcing to local and international customers.Sasha's work is divided across these three primary disciplines. He consults for clients on architecture, development, debugging and performance issues; he actively develops code using the latest bits of technology from Microsoft; and he conducts training classes on a variety of topics, from Windows Internals to .NET Performance. You can read more about Sasha's work and his latest ventures at his blog: http://blogs.microsoft.co.il/blogs/sasha. Sasha writes from Herzliya, Israel. Sasha is a DZone MVB and is not an employee of DZone and has posted 160 posts at DZone. You can read more from them at their website. View Full User Profile

Low-Latency GC in .NET 3.5

08.14.2008
| 7971 views |
  • submit to reddit

GC flavors are a static performance optimization for the .NET garbage collector.  Under various circumstances, applications can opt-in (before runtime) to a runtime mode that affects the GC’s behavior to better suit the specific application in question.  For a succinct yet complete description of GC flavors, Maoni’s blog is a great source of information.

.NET 3.5 (or .NET 2.0 SP1) adds an additional API that can change the GC flavor under some circumstances. It is available as the System.Runtime.GCSettings class, which has two properties: IsServerGC and LatencyMode.

The IsServerGC property is a read-only property that specifies whether the application is running under the server GC. It can't be used to opt into server GC at runtime – it only reflects the state of the application's configuration or the CLR host's GC flavor definition.

The LatencyMode property, on the other hand, takes the values of the GCLatencyMode enumeration, which are: Batch, Interactive and LowLatencyBatch corresponds to server GC (it is the default and the only possible value when server GC is enabled) or to non-concurrent workstation GC; Interactive corresponds to concurrent workstation GC.  Note that if the application is running under workstation GC, the LatencyMode property can be used to switch between concurrent and non-concurrent GC at runtime.

The final, most interesting value of the GCLatencyMode enumeration is LowLatency, which is only available when using workstation GC. This value signals to the garbage collector that your code is currently in the middle of a short-term time-sensitive operation where a garbage collection might be harmful. This is not the value of choice if you're about to execute missile-guiding code for reasons to be seen shortly. It is useful, however, if you're in the middle of performing a UI animation, and a garbage collection will be disruptive for the user experience.

The low latency garbage collection mode implied by the LowLatency enumeration value instructs the garbage collector to refrain from performing full collections unless absolutely necessary – e.g., if the operating system is running low on physical memory (the effects of paging could be even worse than the effects of performing a full collection). Low latency does not mean the garbage collector is off – partial collections (of the low generations) will still be performed – but the garbage collector's share of the application's processing time will be significantly lower.

Using the low latency GC mode can be tricky because forgetting to reset it back to the previous value can result in disastrous consequences. Additionally, the amount of time you want to spend with a low latency GC mode must be kept to a minimum – the long-term effects once you exit the low latency mode and the GC aggressively begins to reclaim unused memory can hinder the application's performance. Finally, if you don't have full control of all allocations taking place within your process (e.g. if you're hosting plug-ins or have multiple background threads doing independent work), remember that switching to the low latency GC mode affects the entire process, and can cause undesired effects for other allocation paths.

The only safe way of using the low latency GC mode is within a constrained execution region (CER), because it is the only way of guaranteeing that the latency mode will revert to its previous value. The following code (snipped from Chris Lyon’s blog) demonstrates how this can be accomplished:

GCLatencyMode oldMode = GCSettings.LatencyMode;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
// perform time-sensitive actions here
}
finally
{
GCSettings.LatencyMode = oldMode;
}

When using the low latency GC mode, it is advisable to force garbage collections at safe points when it is known that the time-sensitive work has idled and can afford pausing to perform a collection. Staying in low latency mode without performing a collection for a long period of time might result in out of memory conditions. Generally speaking, if the application is sensitive to garbage collection timing, it's reasonable to force a collection during idle times to influence a biased redistribution of garbage collection overhead into the idle run time regions.

References
Published at DZone with permission of Sasha Goldshtein, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)