Weak References

Posted: August 9, 2008 in .NET, CLR
Tags: ,

Last sunday we had a session on .NET Internals as part of the monthly session of Kolkata .NET User group.The session went very well.But the discussion on what exactly happens for GC of a WeakReference class remained open ended.After going through Jeffrey Richters book “CLR via C#” I found lot of information on how the WeakReference class works.
For every app domain CLR maintains a table called GC Handle table.This table can be accessed via the System.Runtime.InteropServices.GCHandle class.Along with GCHandle there is an enumeration called GCHandleType which needs to be passed to the Alloc method of GCHandle class
The four values of this enumeration are:
1)Weak – This handle type is used to track an object, but allow it to be collected. When an object is collected, the contents of the GCHandle are zeroed. Weak references are zeroed before the finalizer runs.
2)WeakTrackResurrection-This handle type is similar to Weak, but the handle is not zeroed if the object is resurrected during finalization.

3)Normal-This handle type is used to track an object and prevent its collection by the garbage collector. This enumeration member is useful when an unmanaged client holds the only reference, which is undetectable from the garbage collector, to a managed object.

4)Pinned-This handle type is similar to Normal, but allows the address of the pinned object to be taken. This prevents the garbage collector from moving the object i.e. perform compaction.

WeakReference class is wrapper around GCHandle class with the GCHandleType –  Weak and WeakTrackResurrection.WeakReference constructor calls to GCHandle’s Alloc method and Target is same as the Target property of GCHandle class.

One of the overloaded constructor of this class is WeakReference(Object, Boolean).The boolean parameter if false then it is called a short weak reference otherwise a long weak reference.By default it is always short weak reference.

Short Weak Reference

The target of a short weak reference becomes null when the object is reclaimed by garbage collection.(Weak)

Long Weak Reference

A long weak reference is retained after the object’s Finalize method has been called. This allows the object to be recreated, but the state of the object remains unpredictable.(WeakTrackResurrection)

The GC in the marking phase also scans this GC Handle table to identify the object is reachable/unreachable.

As per MSDN Guidelines for Using Weak References are

 Use long weak references only when necessary as the state of the object is unpredictable after finalization.

 Avoid using weak references to small objects because the pointer itself may be as large or larger.

 Avoid using weak references as an automatic solution to memory management problems. Instead, develop an effective caching policy for handling your  application’s objects.

I found a very good suggesstion in Jeffrey Richters book in this regard.GC does not occur when the memory is full but occurs when the Generation 0  becomes full which is after 256 KB of memory allocation.So using WeakReference might lead to collection & re-creation of a memory intensive object  even when there is no memory crunch.This can result in significant performance hit.So while using WeakReference for caching scenario we have to  strike a balance between memory usage and appliaction performance.The caching algorithm needs to be designed with care and adhoc usage of  WeakReference will not solve the problem.

  1. Debjit Kar says:

    Indeed one should take great care before using WeakReference. It also needs to be seen whether there can be any alternative to the solution or not. Immediately one solution comes to mind is Object/Resource pooling.

    More to continue….

  2. sankarsan says:

    I agree that we need to take a deeper look into usage of WeakReference.
    I was just wondering how Pooling can come into picture here.Normally we cache a chunk of information for faster access.Here we are thinking of WeakReference to reduce memory pressure.If we keep pool of object which we are caching how it’ll add value???

  3. Debjit Kar says:

    Ok… so our goal here is to minimize memory pressure. Precisely what we understand by that is the entire process from object creation to finalize/destruction. The less number of creation/destruction the less memory threshold thus less pressure. So object pooling solves two major performance bottlenecks for high concurrency environment. One its reduces the amount of memory used and two it makes execution faster by cutting the down the GC cycle as minimum as possible.

    A simple story… i created a pooled class object and created/fetched the object in 1000 threads concurrently. To my wonder after the test only 3 objects of that class was created. Now think the amount of response time, memory i saved. Don’t forget the low on GC too.

    1000 object creation/destruction (non-pooled) vs 3 object creation/destruction (pooled).

    In the case of ‘WeakReference’ why even create that object for whatever small timeline it may be… just create it for first time and reuse it. That way you are also helping the CLR by making them do less work for you.

    Happy Programming !

  4. Debjit Kar says:

    Hi sankarsan … don’t keep a pool of object ready hand. Create it on first use then reuse it from pool.

  5. sankarsan says:

    Hey man that’s a great insightful analysis.
    But I still have one doubt.
    Let’s say I am planning to cache x MB of data in Web Server.
    I am concerned with x MB itself.I feel that’s might be too much for peak load of the server.So I am thinking of WeakReference,better caching algo and blah-blah.
    But in your case I will land up with 3x MB of data irrespective of the fact I do a eager/lazy instantiation of the pool
    How do this address my core problem..

  6. Debjit Kar says:

    I was not really presenting a solution for data caching. We don’t usually use object pooling mechanism to cache data though a re-modified version can be used to cache data efficiently… but that is beyond the scope of this article.

    If you are considering ‘WeakReference’ to cache objects instances… don’t. Use object pooling instead.

    If you are considering ‘WeakReference’ to cache data… maybe there is still hope. Don’t use object pooling mechanism to cache data since you might end up with lots of unused data in memory (though memories are cheap nowadays… but it isn’t the best solution for caching data).

    Lets come back to ‘WeakReference’ again…

    A few days back i read an article where WR has been used to cache data. I still don’t understand its usage for caching data… I mean why… then yes there can be scenarios where WR is useful provided retrieving/building that data again isn’t costly.

    A quick short usage:

    If you are maintaining some sort list to hold onto some individual record which is used very frequently and building/retrieving that data from some persistent storage isn’t costly, then you can consider holding each record in the list as a weak reference and build an algorithm which would rebuild each record if not present upon request.

    If rebuilding the record is costly don’t use WR.

    After all this i am still not very much convinced with WR. I feel like i am scratching the surface only… maybe that is all WR has got.

    To answer sankarson’s question,

    Yes there can be a much better and powerful data caching solution, i mean industrial grade…

    Build a custom cache manager and expose it to applications via tcp. The pool acts a your own GC. Run a process in the background to clean up objects after a certain threshold or after the data expiry time has reached. Sounds large but it isn’t….

    Lets see if i can put a post on this…. Now back to WR again…

    Happy programming !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.