Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing GC.Collect() to reduce chances of running during time sensitive code?

During an interview, I was asked to come up with a way to ensure a block of code in c# can run in consistent time to meet a hypothetical time requirement. The interviewer mentioned that one way is to invoke the garbage collector to collect before the block of code is executed such that it significantly reduces the probability of the GC running again during that block of code. It was applied to accurate time-based measurements of a medical device, where garbage collection can affect those measurements.

It makes sense to me, but I could not find any information backing that. The general consensus I reviewed is to never call GC.Collect(), and the exceptions did not include this scenario.

Can running GC.Collect() truly reduce the probability of it running anytime soon? Is this the right approach to do this using the .net framework? Does GC.Collect() collect for other CLR programs too or is it only applicable to the current process?

like image 656
ekw Avatar asked Mar 29 '13 21:03

ekw


People also ask

When should you force garbage collection?

Common triggers for garbage collection are Eden space being full, not enough free space to allocate an object, external resources like System. gc(), tools like jmap or not enough free space to create an object.

Is it possible to force garbage collection and how?

You really can't force Java GC. The Java garbage collection algos are non-deterministic, and while all of these methods can motivate the JVM to do GC, you can't actually force it.


2 Answers

Jared's answer is of course excellent. To add a few other points:

Can running GC.Collect() truly reduce the probability of it running anytime soon?

Yes.

Is this the right approach to do this using the .net framework?

I would not want the correctness of software that has human-life-safety-critical functions to depend on probabalistic guesses about the undocumented behaviour of the collector.

That said: you should do a WaitForPendingFinalizers after the collection. Remember, finalizers run on their own thread, and that might be taking up processor time.

Does GC.Collect() collect for other CLR programs too or is it only applicable to the current process?

Collecting cleans up managed memory in the current process, so if you have multiple appdomains in one process, collecting in one appdomain collects in the others. It does not go cross process.

like image 109
Eric Lippert Avatar answered Sep 28 '22 00:09

Eric Lippert


It is definitely possible that running a GC.Collect will reduce the probability that it happens during the code that immediately follows. There are many definitive scenarios you could draw up under which it would have this exact behavior. For example if the very next allocation would cause a collect and the GC.Collect freed at least the amount of memory allocated during the scenario.

However it's something I would never rely on being true. There is absolutely no guarantee that this will be the case. In fact it's possible that the collection wouldn't occur during the scenario and the time to run the forced GC.Collect could exceed the scenario time itself.

The only way to guarantee that GC.Collect won't run during a given scenario is to

  1. Don't allocate any memory
  2. Don't let anyone else call GC.Collect

Extremely hard to guarantee.

like image 28
JaredPar Avatar answered Sep 28 '22 00:09

JaredPar