Unwanted garbage collection

Andrew Troelsen's title “Forcing Garbage” from Andrew C # 2010 and the .NET 4 Platform reads:

"Again, the whole purpose of the .NET garbage collector is to manage memory on our behalf. However, in some very rare cases it may be useful to programmatically force the garbage collection to be collected using GC.Collect (). In particular:

• Your application is about to enter a block of code that you do not want to interrupt with a possible garbage collection. ... "

But stop! Is there such a case when garbage collection is undesirable? I have never seen / read something like this (due to my little development experience, of course). If during your practice you did something similar, please share. This is a very interesting moment for me.

Thanks!

+7
source share
6 answers

I run a site related to recipes, and I keep a massive schedule of recipes and their use of ingredients in memory. Due to the way I rotate this information for quick access, I have to load several gigabytes of data into memory when the application loads before I can organize the data in a very optimized schedule. I create a huge number of tiny objects on the heap that become inaccessible after plotting.

All this is done when loading a web application and probably takes 4-5 seconds. After that I call GC.Collect(); , because I would prefer to require all this memory again instead of potentially blocking all threads during an incoming HTTP request, while the garbage collector cleans up all these short-lived objects. I also think that it is better to clean now, since the heap is probably less fragmented at this time, since my application has not done anything so far. Delaying this can lead to the creation of many more objects, and the heap should be compressed more when the GC starts automatically.

Also, in 12 years of .NET programming, I never came across a situation where I wanted to get the garbage collector to start.

+5
source

Yes, there is absolutely a case when garbage collection is undesirable: when the user is waiting for something, and they have to wait longer because the code cannot continue until the garbage collection is completed.

What Troelsen points out: if you have a certain point when you know that the GC is not problematic and is likely to be able to collect significant amounts of garbage, then it might be a good idea to provoke it then to avoid starting it at a less appropriate moment.

+7
source

The recommendation is that you should not explicitly call Collect in your code. Can you find the circumstances in which this is useful?

Others detailed some, and undoubtedly more. The first thing to understand is not to do this . This is the last resort, explore other options, find out how the GC works, see how your code affects it, follow the recommendations for your projects.

Calling Collect at the wrong point will make your job worse. Even worse, relying on this makes your code very fragile. The rare conditions necessary for making a Collect call, useful or, finally, not harmful, can be completely canceled with a simple code change, which will lead to unexpected OOM, sluggish results and the like.

+3
source

I call this before measuring performance so that the GC doesn't distort the results.

Another situation is testing unit tests for memory leaks:

 object doesItLeak = /*...*/; //The object you want to have tested WeakReference reference = new WeakRefrence(doesItLeak); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Assert.That(!reference.IsAlive); 

In addition, I did not encounter a situation in which this would be really useful.
Especially in production code, GC.Collect should never be found IMHO.

+2
source

This would be very rare, but the GC can be a moderately expensive process, so if there is a specific section that is time sensitive, you do not want this section to be overloaded by the GC.

+1
source

Your application is about to enter a block of code that you don’t use; you want to interrupt a possible garbage collection ....

A very suspicious argument (which, however, is used a lot).

Windows is not an operating system. Your code (Thread / Process) can always be a proactive OS scheduler. You do not have guaranteed access to the CPU.

So, it boils down to: how does the time for the GC-run compare with the time interval (~ 20 ms)?

There is very little data about this hard data, I searched for them several times.

From my own observation (very informal), the gen-0 collection is <40 ms, usually much less. Full gen-2 can work up to ~ 100 ms, possibly more.

Thus, the “risk” of interrupting a GC is of the same order of magnitude as that of another process. And you cannot control the latter.

+1
source

All Articles