Java Reference Objects
The java.lang.ref package was introduced in the Java 2 platform. Before this package was introduced, there were only strong references which are the normal references to objects. The type of the reference determines the reachability of an object, and reachability of an object determines when that object can be garbage collected. Hence if there is a strong reference to an object, which means the object is strongly reachable, the garbage collector (GC) can not reclaim the memory of that object. After the introduction of the java.lang.ref package, there are weaker types of references which give more freedom to the GC. As a result, GC can only collect the objects in the heap as long as they are either unreachable or they are not strongly reachable.
There are four types of references namely strong, soft, weak and phantom references from stronger to weaker reachability, respectively, which define the corresponding reachability states like strongly reachable or phantomly reachable [1]:
- Strongly reachable: An object accessible via a strong reference.
- Softly reachable: An object that is not strongly reachable and accessible via a soft reference.
- Weakly reachable: An object that is neither strongly nor softly reachable, and which is accessible via a weak reference.
- Phantomly reachable: An object that is neither strongly, softly, nor weakly reachable, it has been finalized, and accessible via a phantom reference.
The main motivation of a soft reference (java.lang.ref.SoftReference) is that the objects referred to via these references (or referents) are guaranteed to be collected before an OutOfMemoryError. However this does not mean that the GC always collects these referent objects: it may or may not collect these referents at ordinary GC cycles. Reclamation of these referents depends on the GC algorithm, and the amount of available memory at that GC cycle. Here is an example of using StrongReference which caches objects of type Employee:
SoftReference sr = new SoftReference(some_reference);
// later in the code
Employee e = sr.get();
if (e == null) //employee pointed by this soft reference is garbage collected
{
e = CreateEmployee();
sr = new SoftReference(e); //restore employee e
}
// process Employee e
//clear the strong reference to e so that GC can collect if needed
e = null
First, a SoftReference is created to point to an Employee object, than later in the code the referenct is retrieved, and if it is null this means the GC has already reclaimed the memory of the referent hence a new Employee is created and restored. Otherwise the retrieved Employee is used. After the Employee e is processed, it is set to null so that no strong reference points to e, hence the GC can reclaim the memory if necessary.
In contrast to soft references, the referent objects referred by weak references (java.lang.ref.WeakReference) are always reclaimed by the GC whereas soft references may or may not be reclaimed. Typical uses of weak references are for canonical mappings which are actually one-to-one mappings, and they are used for referring to objects which are inexpensive to recreate, and probably live for a long time. For example, we can have a mapping from the SSN to the Person objects which are loaded from some persistent storage. Weak references allow us to work with huge number of Person objects even the memory is not big enough to hold all of them. So, if the GC reclaims some of these objects, the application can recreate them from the permanent storage. However, if these objects were soft references then the GC would be less free when reclaiming these objects.
Finally, phantom references (java.lang.ref.PhantomReference) can be used for pre-mortem cleanups in a more flexible way than provided by the finalize method. For example, if we need to perform some housekeeping on a shared resource after there are no objects left using that resource, we can do this when the last object becomes phantomly reachable [2]. To understand whether an object is phantomly reachable, the associated java.lang.ref.ReferenceQueue can be used which provides the notification mechanism. The GC places the registered reference object to the reference queue before the memory of the referent is reclaimed. For the details of the java.lang.ref package please see [3].
References:
[1] Guidelines for using the Java 2 reference classes, http://www.ibm.com/developerworks/library/j-refs/
[2] Collaborating with the Java Memory Manager, http://jnb.ociweb.com/jnb/archive/jnbJune2000.html
[3] java.lang.ref package, http://java.sun.com/j2se/1.5.0/docs/api/index.html?java/lang/reflect/package-summary.html
About this entry
You’re currently reading “ Java Reference Objects ,” an entry on Sirius ICT
- Published:
- 10.26.09 / 11pm
- Category:
- Blog, Development Issues, Thougths and Reflections
No comments
Jump to comment form | comments rss [?] | trackback uri [?]