Why You Shouldn’t Rely On WeakReference.IsAlive


The WeakReference class has the property IsAlive.  The problem with it, is that you can only trust it if it returns false.


 


While a WeakReference points to an object that is either live (reachable), or garbage (unreachable) that has not yet been collected by the GC, the IsAlive property will return true.  After an object has been collected, if the WeakReference is short (or if the target object does not have a finalizer) then IsAlive will return false.  Unfortunately by the time IsAlive returns, the target may have been collected.


 


This situation can occur because of the way the GC suspends all managed threads before scanning the heap for garbage and collects it (this is an oversimplified explanation for illustrative purposes).  The GC can run at any time between two instructions.  For example:


 


Foo f = new Foo();


WeakReference wr = new WeakReference(f);


// code goes here …


if (wr.IsAlive)


{


      // Garbage Collection may have occurred here!


      Foo f2 = (Foo)wr.Target;


      Console.WriteLine(f2.ToString());


}


 


If a collection occurred inside the if block, but before the WriteLine, this code would throw a NullReferenceException, since there are no live strong references to f.  The only reliable information IsAlive can give you, is that the object is no longer alive since once it’s dead, it’s dead (even resurrecting the target won’t make IsAlive return true once it thinks the object is dead).


 


The correct pattern for the above code looks like this:


 


Foo f = new Foo();


WeakReference wr = new WeakReference(f);


// code goes here…


Foo f2 = (Foo)wr.Target; // new strong reference


if (f2!=null)


{


      Console.WriteLine(f2.ToString());


}


 


So how is IsAlive useful at all?  You could imagine implementing a cache by using a collection of WeakReferences, and using the IsAlive property to determine if an object still exists, and if not, replenish the cache.  Just be careful to only make decisions based on IsAlive returning false.

Comments (5)

  1. Anonymous says:

    I think that

    1) This information should be in the MSDN help for IsAlive

    2) MSDN help should have an example for WeakReference

    3) IsAlive should be removed from the framework!

  2. clyon says:

    Hi Peter

    We are currently working on updating the MSDN docs, so there should be some more comprehensive examples coming soon.

    Unfortunately, we cannot simply remove IsAlive due to backwards compatibility reasons.  

    -Chris

  3. Anonymous says:

    Weak references is a feature where one object can point to another without holding it. In other words,