I'm trying to test C#'s GC behavior, in order to understand when exactly are objects collected. I've written this code, expecting it to output True and then false, but I see differing behaviors - on my machine and on Programiz it outputs True, True. On dotnetfiddle I get True, False.
WeakReference weakRef;
{
var obj = new object();
weakRef = new WeakReference(obj);
Assert.That(weakRef.IsAlive, Is.True);
obj = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.That(weakRef.IsAlive, Is.False);
Why do I see differing behaviors*? And when I get True, True - when will the strong reference be released, if not when a variable is nullified and out of scope?
in order to understand when exactly are objects collected
Eligible objects are collected when the GC is run, at least for objects in the collected generation. Objects are eligible for collection after the last usage, so setting a reference to null usually have no effect. A interesting thing is that an object might be collected even if a method on that same object is running, as long as there is no chance that any fields will be accessed in any remaining code to be executed.
A major factor that can affect collection is running a debug-build with a debugger attached. This will artificially extend the lifetime of objects to allow them to be inspected.
I'm not sure why your machine does not kill the weak reference, but weak references are rarely used in my experience. The general recommendation is to just leave the GC alone, and don't worry about it. If you really need to investigate how the GC works I would recommend a memory profiler. This should allow you to trigger GCs, and list all the managed objects that are alive from outside your application. A memory profiler will also give you an accurate memory usage, in contrast to the memory usage from the task-manager that some worry about to much.