6

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

Demarsch
  • 1,419
  • 19
  • 39
  • Why are you worried about garbage collection in managed code? Or are you using unmanaged code somewhere? – Equalsk Feb 03 '17 at 11:10
  • Garbage collection in .NET is thoroughly documented, both by Microsoft and by the countless existing questions on Stack Overflow explaining it. See duplicate for exact answer to your concern about memory reclamation. If you have some _specific_ issue that you need solving, post a new question that includes a [mcve] that reliably reproduces your problem, explain what you've done so far to try to solve the problem, and tell us what _specifically_ you need help with. – Peter Duniho Sep 28 '20 at 07:14

1 Answers1

2

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

el-aasi
  • 307
  • 2
  • 18