Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly happens when I ask dotMemory to force garbage collection [duplicate]

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 dotMemoryenter image description here

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

like image 679
Demarsch Avatar asked Feb 03 '17 11:02

Demarsch


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 in?

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.

Can we force the garbage collector to run at any time?

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.


1 Answers

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

like image 189
el-aasi Avatar answered Oct 16 '22 05:10

el-aasi