1

I have a question concerning the GC in C#. According to this topic: C#: should object variables be assigned to null?

The garbage collector will collect a variable, when it is not used anymore in the code thereafter. However if I test it with the following code, the GC collector only collects the variable when it is set to null. (Commented out line) (If not set to null it is alive --> true, if it is set to null it is not alive --> false) What am I missing here?

Coffee coff = new Coffee();
coff.name = "test";
coff.number = 4;

WeakReference test = new WeakReference(coff);
//coff = null;

GC.Collect();
GC.WaitForPendingFinalizers();

Console.WriteLine(test.IsAlive.ToString());

Coffee class consists of the following:

public class Coffee 
{
    public string name { get; set; }
    public string beans { get; set; }
    public int number { get; set; }
}

@Edit 14:56 27-08-2014:

I found the answer inhttps://stackoverflow.com/questions/17130382/understanding-garbage-collection-in-net. It has to do with the following settings. I Qoute:

"You are being tripped up here and drawing very wrong conclusions because you are using a debugger. You'll need to run your code the way it runs on your user's machine. Switch to the Release build first with Build + Configuration manager, change the "Active solution configuration" combo in the upper left corner to "Release". Next, go into Tools + Options, Debugging, General and untick the "Suppress JIT optimization" option."

Community
  • 1
  • 1
Revils
  • 1,478
  • 1
  • 14
  • 31
  • 1
    GC _may_ decide to collect an object if there are no more references, but is not obliged to. – Vlad Aug 27 '14 at 12:44
  • 2
    Did you run the code with the debugger attached or without? – Scott Chamberlain Aug 27 '14 at 12:44
  • 2
    Actually there is a reference to it via local variable anyway. – Andrey Aug 27 '14 at 12:45
  • 4
    Is it not that since your `GC.Collect` is in local scope, `coff` is holding a reference to the object so it's not eligible for GC? (the setting to `null` removes any link to the GC root) – Charleh Aug 27 '14 at 12:45
  • 1
    Run the test in release mode and out of the debugger! – Sriram Sakthivel Aug 27 '14 at 12:47
  • 1
    @Charleh: well, optimizer is in its full right to throw out `coff` after it's used the last time. – Vlad Aug 27 '14 at 12:47
  • 4
    @Charleh and Andy, you are incorrect in your assumptions. If you are not running with the debugger a object can be collected even if a local variable has a refrence, iff no more uses of that variable exist in the function at the point of the GC running. – Scott Chamberlain Aug 27 '14 at 12:47
  • 1
    @Andrey and Charleh That doesn't matter. GC know it is no more used with the help of jit compiler. and hence eligible for garbage collection. – Sriram Sakthivel Aug 27 '14 at 12:48
  • I assume this is only at runtime without the debugger attached though? Does the debugger being attached make the difference here? – Charleh Aug 27 '14 at 12:52
  • @ScottChamberlain can you prove your point? How can GC figure out that variable will not be used in code further? I always thought that it just traverses the graph starting from roots (incl local variables). What could be done is that compiler can release local variables after last use and so let GC do its deeds. – Andrey Aug 27 '14 at 12:52
  • Maybe this is a strange question, but how can I make the variable be collected by GC without setting it to null? – Revils Aug 27 '14 at 12:53
  • 1
    @Sliver2009 Well if Coffee implements IDisposable you can `.Dispose()` it, or wait for it to leave scope. But in either of those cases, it is indeterminate when it will actually be collected. Even if you `GC.Collect`, unless it is in a different scope I don't think it will collect it. – helrich Aug 27 '14 at 13:19
  • @helrich I understand it, but I thought the IDisposable interface is mainly for the disposal of unmanaged resources? So what I conclude from your answer is that the only way to be sure that it will be collected, is by setting it to null? – Revils Aug 28 '14 at 05:58

0 Answers0