#740 – Short vs. Long Weak References

You can create a WeakReference object that refers to a regular reference-typed object and lets you discover whether the original object has been garbage collected or not.  You can use the Target property of the WeakReference to reference the original object, if it’s still alive.

By default, a WeakReference object creates a short weak reference–the target of the weak reference becomes null and the IsAlive property reports false as soon as the object’s finalizer is called, but potentially before the object is actually garbage collected.

You can also create a long weak reference by passing a value of true as the second parameter to the WeakReference constructor.  The Target will remain non-null after the object has been finalized, up until the point in time when it actually gets garbage collected.  In this way, you retain access to an object that has been finalized, but not collected.

Advertisements

#736 – Target of a WeakReference Will Be null after Garbage Collection

You can create a WeakReference object that refers to a regular reference-typed object and lets you discover whether the original object has been garbage collected or not.  The IsAlive property of the WeakReference can be used to determine whether the object has been garbage collected or not.  (Although a value of true can’t be trusted).

You can use the Target property of the WeakReference to reference the original object, if it’s still alive.  However, if the original object has already been garbage collected, the Target property will be null and you can then no longer reference the original object.

            Dog dog = new Dog("Bowser");

            WeakReference dogRef = new WeakReference(dog);

            // Bowser gets garbage collected
            dog = null;
            GC.Collect();

            Console.WriteLine(string.Format("Object still alive: {0}", dogRef.IsAlive));

            // dogRef.Target will now return null, since
            // original Dog object was garbage collected
            Dog origDog = (Dog)dogRef.Target;
            if (origDog != null)
                origDog.Bark();
            Console.WriteLine("Bowser is gone..");

736-001

#735 – Don’t Trust WeakReference.IsAlive If It Returns true

The WeakReference.IsAlive method can tell you if a particular object is still alive, i.e. it has not yet been garbage collected.  However, when IsAlive returns true, you can’t then necessarily interact with the object through its weak reference, because it could be garbage collected before you get a chance to use it.

For example:

            WeakReference dogRef = new WeakReference(dog);

            // Later, try to ref original Dog

            if (dogRef.IsAlive)
            {
                // Oops - garbage collection on original Dog could occur here
                ((Dog)dogRef.Target).Bark();
            }

You can trust IsAlive when it returns false, since a garbage collected object is not in danger of being reconstituted.  But the correct pattern for checking to see if an object is still alive is:

            WeakReference dogRef = new WeakReference(dog);

            // Later, try to ref original Dog

            Dog origDog = (Dog)dogRef.Target;
            if (origDog != null)
            {
                origDog.Bark();
            }

#734 – Accessing the Original Object Referenced through a WeakReference

You can create a WeakReference instance that refers to an object and then use the WeakReference to determine whether the object has been garbage collected.

You can also refer back to the original object referenced by the WeakReference using its Target property.

            Dog dog = new Dog("Bowser");

            WeakReference dogRef = new WeakReference(dog);

            Dog origDog = (Dog)dogRef.Target;

When you refer to the original object in this way, you add a reference to it, which means that it won’t get garbage collected.

            Dog dog = new Dog("Bowser");

            WeakReference dogRef = new WeakReference(dog);

            Dog origDog = (Dog)dogRef.Target;

            dog = null;
            GC.Collect();

            // Bowser still alive at this point, since we still have
            // a reference to him.

            Console.WriteLine(string.Format("Object still alive: {0}", dogRef.IsAlive));

734-001

#733 – How to Tell If an Object Has Been Garbage Collected

You normally can’t tell whether an object has been garbage collected by using some reference to the object–because once you have a reference to the object, it won’t be garbage collected.

You can instead create a weak reference to an object using the WeakReference object.  The weak reference is one that won’t be counted as a reference, for purposes of garbage collection.

In the code below, we check before and after garbage collection to show that a Dog object is garbage collected.

            Dog dog = new Dog("Bowser");

            WeakReference dogRef = new WeakReference(dog);
            Console.WriteLine(dogRef.IsAlive);

            dog = null;
            GC.Collect();

            Console.WriteLine(dogRef.IsAlive);

733-001