TheDeveloperBlog.com


C# WeakReference Example

WeakReference influences the garbage collector. Most objects that are referenced must be kept in memory until they are unreachable. But with WeakReference, objects that are referenced can be collected.


Example. First, as we begin, please notice that the WeakReference type is created using a constructor call. You must pass the object reference you want to point to the constructor. Here we use a StringBuilder object.

Constructor

In the middle of the program, the garbage collector is run using GC.Collect. After this call, the object pointed to by the WeakReference no longer exists. If you don't call GC.Collect, the object will almost certainly still exist.

GC.Collect
C# program that uses WeakReference

using System;
using System.Text;

class Program
{
    /// <summary>
    /// Points to data that can be garbage collected any time.
    /// </summary>
    static WeakReference _weak;

    static void Main()
    {
	// Assign the WeakReference.
	_weak = new WeakReference(new StringBuilder("perls"));

	// See if weak reference is alive.
	if (_weak.IsAlive)
	{
	    Console.WriteLine((_weak.Target as StringBuilder).ToString());
	}

	// Invoke GC.Collect.
	// ... If this is commented out, the next condition will evaluate true.
	GC.Collect();

	// Check alive.
	if (_weak.IsAlive)
	{
	    Console.WriteLine("IsAlive");
	}

	// Finish.
	Console.WriteLine("[Done]");
	Console.Read();
    }
}

Output

perls
[Done]

IsAlive. One important property on the WeakReference type is the IsAlive property. This is a boolean property that indicates whether the object pointed to by the WeakReference has been collected or not.

The Target property returns an object that contains the reference to the instance you stored in the WeakReference. You should cast the object using the as-operator or the explicit cast before using the instance.


Discussion. Is using the WeakReference type a good idea for most programs? Unfortunately, the behavior of the garbage collector is not always predictable and can even vary when the runtime is updated.

Also: Using caches that are too large will cause reductions in performance because of memory locality degradation.

Thus: WeakReference seems like an unideal solution for performance work. Perhaps a time-based expiration scheme could be more effective.

The best description of the theory and practical implementation of garbage collection I have read is found in the dragon book, Compilers: Principles, Techniques, and Tools. It is not specific to the .NET Framework.

But: This book describes in great detail how garbage collection works. It helps us understand the concepts.


Summary. The WeakReference type influences the behavior of the garbage collector. When a collection is done, either forced or invoked by the runtime, objects that are only referenced through WeakReference can be collected.

Therefore: You must check these objects for life upon each access. This makes code more complex.