Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to suppress gen 2 GC collection in .NET?

My program allocates a very large number of instances that comprise a long-lived DAWG. During the construction of this DAWG, there are times when the progress slows down 100 fold, and this correlates perfectly with .NET performing gen 2 GC collections. During these periods, the "% time in GC" is 99.5%, and the "total gen 2 collections" increments every few seconds. After several back-to-back gen 2 collections, they stop triggering for no obvious reason and the program speeds up again. A few minutes later, the cycle restarts.

The number of instances I create is on the order of 25 million, and they take up several GB of RAM, so it's not too surprising that the gen 2 collections take this long. What is surprising is that gen 2 collections come in "trains", and get triggered continually.

Can I somehow prevent this without completely rethinking my approach? Perhaps there's some way to ask .NET to suspend gen 2 collections until further notice? The program runs very efficiently apart from these occurrences, so .NET is clearly quite up to this task apart from this unfortunate corner-case behaviour.

(I tried setting GCSettings.LatencyMode to GCLatencyMode.Batch, but the issue remained. The amount of free physical RAM at the time the GCs start happening is around 1GB. This is on a 64-bit machine.)

like image 859
Roman Starkov Avatar asked Nov 21 '11 22:11

Roman Starkov


People also ask

Can we suppress the garbage collector C#?

You can not disable garbage collection using any .

Can we suppress the garbage collector?

You can't force garbage collection in Java. There are some strategies you can use to get the Java virtual machine to prioritize the task, but the indeterminate nature of garbage collection means the process can't be forced. Similarly, you can't stop Java garbage collection from happening, either.

How many generation does the net GC usually have?

Generations. The . NET Garbage Collector has 3 generations and each generation has its own heap that that is used for the storage of allocated objects.

What is Gen 2 heap size?

"Gen 2 heap size" counter is 17gb. "# Gen 2 collections" counter is 3600 (which means there is full gc cycle once every 2.5 minutes, which is good for us) Average Gen2 collection takes about 300ms. Calling GC.


1 Answers

In .NET 4.5+ you can specify your preference for fewer Gen 2 collections by using the new GCLatencyMode options.

GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;

More info here:

http://blogs.msdn.com/b/dotnet/archive/2012/07/20/the-net-framework-4-5-includes-new-garbage-collector-enhancements-for-client-and-server-apps.aspx

My app cannot tolerate pauses during a certain time window

A growing subset of .NET developers has built commercial apps and services that deliver results according to defined business requirements or SLAs. Stock markets are examples of services that must deliver very timely results while markets are open. Typically, these apps perform significant work during the time when they want to deliver low-latency results. Yet they cannot tolerate noticeable pauses due to a collection.

Our customers have told us that they would deploy more memory on their servers if doing so would remove long pause times (which are typically introduced by full blocking GCs). In the .NET Framework 4.5, we provided that option by introducing SustainedLowLatency mode, which avoids full blocking GCs. This mode is also available for the workstation GC in the .NET Framework 4 via Update 4.0.3.

While the SustainedLowLatency setting is in effect, generation 0, generation 1, and background generation 2 collections still occur and do not typically cause noticeable pause times. A blocking generation 2 collection happens only if the machine is low in memory or if the app induces a GC by calling GC.Collect(). It is critical that you deploy apps that use the SustainedLowLatency setting onto machines that have adequate memory, so they will satisfy the resulting growth in the heap while the setting is in effect.

In the .NET Framework 4.5, SustainedLowLatency mode is available for both workstation and server GC. To turn it on, set the GCSettings.LatencyMode property to GCLatencyMode.SustainedLowLatency. The .NET Framework 4 includes a LowLatency mode for workstation GC; however, this setting is only intended to be used for short periods of time, whereas SustainedLowLatency mode is intended to be used for much longer.

There is also NoGCRegion that you can try.

https://msdn.microsoft.com/en-us/library/system.runtime.gclatencymode%28v=vs.110%29.aspx

Indicates that garbage collection is suspended while the app is executing a critical path. NoGCRegion is a read-only value; that is, you cannot assign the NoGCRegion value to the GCSettings.LatencyMode property. You specify the no GC region latency mode by calling the TryStartNoGCRegion method and terminate it by calling the EndNoGCRegion method.

like image 114
jocull Avatar answered Sep 21 '22 03:09

jocull