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?
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.
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.
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.
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
GC.Collect
Extremely hard to guarantee.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With