When I first read about weak references in .NET more than 5 years ago back my first thought was to use it for Caching. The concept was already present in Java before .NET since Java had garbage collection before. Still today I don't see many developers using this awesome class.

What is a Weak Reference?

We all know that garbage collectors start cleaning memory for objects that do not have any reference. A weak reference is a way to have some pointer to an object that does have any reference (strong reference). When we need to access a weak referenced object we can just check if the object is alive and then access it if the object is alive at all. Since .NET is a garbage collection based runtime environment, like all GC based runtimes it does not immediately clean up the memory allocated for the instantiated objects.

Why should we use it?

Not having a strong reference to the object but at the same time having a pointer to the object enables this class to be well suited for caching.

When to use Weak Reference?

Since GC executes when there is memory pressure and cleans objects that are in memory. At the same time if memory and processing is expensive for your application then you can reduce pressure on memory and processing at the same time. Let try an example ...

Lets assume that we have an object that contains is 500KB of data and when we fetch it it quite expensive to get because of the IO operation required to fetch it from database and we need to validate it with some rule. And at the same time we have to have 1000 of these objects instantiated with different sets of data.

We can use traditional cache but that would use too much memory or we can fetch the instance each time for database. Both solutions have its own flaw. The first uses too much memory and the second one uses too much processing. This would be the best solution to use weak reference

There are 2 cases possible when we need to access any instance of the object in question

1. It may not be garbage collected: So the object is still in memory and we can associate a strong reference to it and use it. This saves performance but uses memory without any extra pressure since GC takes the best decision when to collect.

2. It may have been collected and does not exist anymore: In this scenario we will fetch the object again. So we would be using processing power. The memory pressure was high and GC decided to collect and our onject went with that so we need to fetch the object again. Here again we are letting GC decide when the memory pressure is enough that we would to a high processing action.

So the basic belief behind WeakRefernce is that "GC knows best". It will clean up memory when needed and we puny humans should respect its decision on memory management.

How to use WeakReferences?

All you need to do is create a WeakReference class with the object in question passed into the constructor. Keep a storng refence to the weak reference object. When need later then check if obect is alive by checking 'IsAlive' property and then use it. The code sample below shows the lifetime of an object when using a weak reference ...

// Create the objectBook book = newBook("My first book", "Me");// Set weak referenceWeakReference wr = newWeakReference(book);// Remove any reference to the book by making it nullbook = null;

Since the garbage collector runs on a different thread, your wr.IsAlive check could return true, but then your wr.Target as Book could return null, which would then cause a NullReferenceException at runtime.

Amit: Thanks a lot for the wishes, I am just trying to grow a writing habbit.

Moim: Great to hear that you are reading my blog, Thanks.

Judah: Yes, I wrote that snippet at that way first, then thought why don't I show the IsAlive use of property. Since GC runs in a different thread, in real life one must cast and check for null. I agree, I will update the snippet later.

Does C# have soft references like Java does? In Java, this would be the prefered approach since a weak reference will be garbage collected even if there is no memory pressure. For a cache, you'd want it to gracefully shrink down as more important tasks require memory and the VM has determined that its becoming a scarce resource. The point of a cache is keep frequently used data, and I think a weak reference approach would have too high of a churn rate be very effective.

Another aspect, at least in Java, is that a reference queue is guarded by a lock (synchronize). If only one queue is used, then this can cause poor performance due to high lock contention. You'd want to have a reference queue per bucket if you built a hashtable-based cache.

Unfortunately no. C# does not have soft references. It would have been great to have soft references, since then I could also apply different modes to GC if it had any and customize my requirements of churn.

Nice post.
I found so intriguing the fact that since 2002, you are the first one I know to blog about WeakReference.
This class is a powerfull tool for architectural empowerment, and it's a pity that there isn't so much literature on the web about it.

This is because these are weak reference, not soft references. So, the garbage collector will clean up the cache too often for this approach to be effective. Especially on release builds, the .NET GC can be quite aggressive.

Hi Shafqat h r u , my name is Faisal Zubair i have read your article regarding weak reference but could not get few points which i would like to ask you.When garbage collector runs it will remove all objects whose reference is null and also remove weak reference then why we use weak reference , what is the purpose of it or advantage of it? Please reply as soon as possible.

Use weak references when you think you might need the object in future, but if there is memory pressure they will be removed. So if you have any object which don't need immediately but might need in "near future" ( meaning before gc collects)

So if you have an object loading which is expensive but you dont want to hold on to it. You'd be happy if its there next time you want it, if not you would reload it, then weak reference is your thing.

There are a lot of references in the net on weak ref, it is present in most standard languages like java, python ect.