By default, when we use a "new" operator, we get hold of a strong reference. A strong reference to an object prevents the Garbage Collector from removing the object from the Heap. The GC will not garbage collect any object as long as there are one or more strong references to it.
While this is the behavior we expect most of the times, there are times when we may not want to hold a strong reference to an object and prevent it from getting garbage collected.
A typical example of this is a Cache. While implementing a home grown Cache mechanism, it would be good to make use of what are called "Weak References". A weak reference allows the garbage collector to collect the object while still allowing the application to access the object. This means that in the intermediate time when there are no strong references to the object and till the time the garbage collector has not as yet collected the object from the heap, the object is accessible via the weak reference.
Example where Weak Reference can be used:
Lets say there is a huge DataSet that we are maintaining in memory. The DataSet is displayed to the user on one page. Now, the user visits another page of the application and therefore now the DataSet maintained in memory is not really required. Before the user moves to another page, what we can do is nullify the strong reference to the DataSet while maintaining only a weak reference to it. What this means is, while the user visits other pages of the application, if at all GC runs and needs to free the memory, the DataSet can be garbage collected. In case other pages do not need a lot of memory, GC will not run and the DataSet will not be garbage collected. If at all the user visits the same page again, the DataSet will still be in memory and can be referenced using the Weak Reference. Thus, a weak reference makes sure that we do not unnecessarily hold on to big objects in memory and prevent the GC from garbage collecting it.
The basic pattern for the use of a WeakReference would look like this:
// Create a weak reference to the DataSet ds.
private WeakReference Data = new WeakReference(ds);
// Get Data method that makes use of the Weak Reference
public DataSet GetData(){ DataSet data = (DataSet)Data.Target; if( data !=null) { return data; } else { data= GetBigDataSet() // load the data .... // Create a Weak Reference to data for later use... Data.Target = data; } return data;}
It would be clear by now how Weak References help when implementing a Cache. A cache can always maintain weak references to objects, which means that if memory needs to be cleaned up, objects in the cache that are no longer strong referenced can be picked up by GC freeing up the memory.
Note: While Weak Reference is a good thing for saving on memory utilization, weak references should be used only for large objects preferrably, because with small objects, the weak reference pointer itself could be larger than the actual object.
Friday, May 18, 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment