2

I am working with this code as an example:

var p = new person("Amir"); var zp = new person("Amiraa"); GC.Collect(); GC.WaitForPendingFinalizers(); class person { public person(string nName) { Console.WriteLine("New"); string name = nName; } ~person() { Console.WriteLine("Garbage collected"); } } 

But the resault on the console only shows "New", not "Garbage collected". so why is the gc not working?

2
  • Bear in mind that a) garbage collection does work in .NET and b) it's intended to let you not have to think about when objects are collected. Commented Jan 12, 2022 at 9:28
  • Destructor in c# are very non deterministic. See this answer from Eric Lippert: stackoverflow.com/questions/44573392/… Commented Jan 13, 2022 at 1:18

1 Answer 1

6

Play around, and you'll notice that your code works as expected in Release, but not necessarily Debug.

This is because the variables p and zp are still in scope at the point that you call GC.Collect(). They still refer to the person instances.

In Release, the GC will happily collect objects referenced by variables which are still in scope, so long as they are not used again. In Debug, the debugger needs to let you view the contents of all variables which are in scope, so the GC can't collect them.

If you do:

var p = new person("Amir"); var zp = new person("Amiraa"); p = null; zp = null; GC.Collect(); GC.WaitForPendingFinalizers(); 

You'll see the output you expect, even in Debug. Note that the tiered compilation introduced in .NET 6 affects this, and the above test might not work as expected.

If you introduce a separate method, so the lifetimes of p and zp are explicitly scoped, you should see the expected behaviour even on .NET 6 in Debug:

Test(); GC.Collect(); GC.WaitForPendingFinalizers(); void Test() { var p = new person("Amir"); var zp = new person("Amiraa"); } 
Sign up to request clarification or add additional context in comments.

6 Comments

Hey, Yes I thought about that - but still it is not working, I am not getting the GB. (still console only shows new).
See the links in my answer - they show the output I describe. If you're seeing something different, then I'm afraid I can't reproduce it. Make sure you can reproduce what you're seeing on a site such as sharplab.io or dotnetfiddle.net
The link you send also only write "new" to the console. it does not show the output from the ~(person)
See the "Release" link. Interestingly the output from the p = null seems to have changed...
Yes I see your point. but for some reason it does not show on .vs 2022
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.