I use dotMemory to profile my application and I noticed the below behavior: inside my code there are some points where I perform garbage collection manually by using
GC.Collect();
GC.WaitForPendingFinalizers();
Inside dotMemory I see that memory is actually freed in these points but if after that I click 'Force GC' even more garabage is collected. What is the way they are doing this and why that memory was not collected by my code and is it possilbe to achieve the same level of collection?
I'm attaching the screenshot where you can see that the gen 2 is almost halved by dotMemory
I've also tried to perform multiple collections i.e.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
and even though it seems to reclaim a bit more memory it never comes close to how dotMemory performs
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.
Running the Garbage CollectorYou can ask the garbage collector to run at any time by calling System 's gc method: System. gc(); You might want to run the garbage collector to ensure that it runs at the best time for your program rather than when it's most convenient for the runtime system to run it.
From JetBrain's Forum :
The "Force GC" button calls GC from native code.
When you call GC.Collect() method from your code, it performs the next steps:
Release memory which can be released immediately Find the objects which have Finalize methods and put them in a queue GC.Collect() release only managed object. Besides, CLR has several different GC strategies that are applied depending on the situation to minimize delay which caused GC and we can't affect it. Native memory which used by managed objects will never be released if these objects don't have a Finalize method or this method is implemented incorrectly.
We can suggest you to call WaitForPendingFinalizers method with GC.Collect and repeat it several times:
for (int i = 0; i < 4; i++)
{
GC.Collect(2, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
}
It can show the better result but we can't guarantee that this code will lead to the same results as Full GC called from native code.
GC.Collect method: https://msdn.microsoft.com/en-us/library/hh138633(v=vs.110).aspx
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