I was experimenting using the WeakReference class but I didn't expect that it doesn't keep the object from the next garbage collection. Why?
I don't have the knowledge of the practical use of this class.
The code forces another garbage collection after I set the myObject to null.
Edit: On the end of else if line the myObject is not disposed, is it because the compiler knows that WeakReference wr object is still used in the code so that the garbage collection does not reclaim it?
class Program
{
static void Main(string[] args)
{
MyObject myObject = new MyObject(25);
WeakReference wr = new WeakReference(myObject);
if (wr.IsAlive) Console.WriteLine("Alive");
myObject = null;
GC.Collect();
if (wr.IsAlive) Console.WriteLine("Still alive");
else if(!wr.IsAlive) Console.WriteLine("Dead");
//
//edit: added this
GC.Collect();
if (wr.IsAlive) Console.WriteLine("Still alive");
else if (!wr.IsAlive) Console.WriteLine("Dead");
//edit end
Console.ReadKey();
}
}
class MyObject : IDisposable
{
private bool disposed = false;
private int id = 0;
public MyObject(int id)
{
this.id = id;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
Console.WriteLine("disposed {0}", id);
if (!disposed)
{
if (disposing)
{
//free managed
}
//free unmanaged
disposed = true;
}
}
~MyObject()
{
Dispose(false);
}
}
On the end of else if line the
myObject
is not disposed, is it because the compiler knows thatWeakReference
wr
object is still used in the code so that the garbage collection does not reclaim it?
No, it is because you run the application with a debugger attached. Please read @Hans Passant's answer here for details.
If you build the application in release mode and run it without a debugger attached, you should see "Alive", "Dead" and "Dead" being printed to the console. I do.
You should also remove the finalizer from your MyObject
class since you are using no unmanaged resources.