Here we are going to discuss about the StrongReference, PhantomReference, WeakReference and SoftReference. Reference classes are important in the context of how garbage collection works in Java memory model.
Garbage collector reclaims memory from objects which are eligible for garbage collection and this eligibility is decided upon what kind if reference is pointing to the object – WeakReference or SoftReference or PhantomReference.
Garbage collector reclaims memory eagerly from an object if WeakReference is pointing to it. On the other hand, an object with SoftReference is garbage collected if JVM absolutely needs memory.
SoftReference is useful in the situation, for example, when you need to implement cache for your application.
Whereas WeakReference is useful in the situation, for example, when you need to store metadata, i.e., ClassLoader reference. So if no class is loaded then you don’t need to keep the reference of ClassLoader.
ThreadLocal uses WeakReference internally. ThreadLocal values are stored into Threads. When a thread dies, all of its values through its ThreadLocal are garbage collected.
If you have a ThreadLocal as a final class member, which is a strong reference (StrongReference), then it won’t be garbage collected untill the class is unloaded.
Another simple example of StrongReference could be:
String name = "Soumitra"
The above code is written inside a class and the variable name has a strong reference to the String object name.
Obviously, the above String object is strong reference and required for the Java program. This kind of strong reference is not eligible for garbage collection.
Another example of WeakReference is WeakHashMap, where keys are weak referenced, with unique feature from other implementations of Map interface.
Java API already provides java.lang.ref.WeakReference class for creating WeakReference object, for example:
Vehicle vehicle = new Vehicle(); WeakReference<Vehicle> wkVehicleRef = new WeakReference<Vehicle>(vehicle); vehicle = null;
In the above code snippets, the first line, i.e., the vehicle object is a strong reference. The second line creates an object of WeakReference for vehicle. The third line where we assign null to vehicle object is eligible for garbage collection.
Remember, once the object is eligible for garbage collection does not imply that this object gets cleaned up immediately, rather it solely depends on the garbage collector when it reclaims the memory from this object.
To get an object from WeakReference you need to use wkVehicleRef.get() and it may happen that you would get either actual vehicle object or null depending upon whether the object has already been cleaned up or not.
On the other hand had this been SoftReference instead of WeakReference, the vehicle object was not eligible for garbage collection.
The SoftReference class is represented by java.lang.ref.SoftReference. The SoftReference can be created for the above example as follows:
Vehicle vehicle = ... SoftReference<Vehicle> sftVehicleRef = new SoftReference<Vehicle>(vehicle); vehicle = null;
Now in the above code snippets, the vehicle object being SoftReference is not eligible for garbage collection unless JVM absolutely needs to reclaim the memory. Therefore garbage collector does not aggressively reclaim the memory for SoftReference objects unless there is no other option.
In case memory is absolutely needed by JVM and there is no other option but clear out the soft referenced objects, then the garbage collector clear out all soft referenced objects before JVM throws OutOfMemory error.
Another kind of reference, which is called PhantomReference represented by java.lang.ref.PhantomReference class and the object pointed by PhantomReference can be garbage collected any time whenever garbage collector likes to collect it.
PhantomReference can be created as given in the below example:
Vehicle vehicle = ... PhantomReference<Vehicle> phntmVehicleRef = new PhantomReference<Vehicle>(vehicle); vehicle = null;
PhantomReference is the weakest level of reference in Java programming language.
If we arrange the order of references, then order becomes strong -> soft-> weak -> phantom.
An object is phantomly referenced after it has been finalized.
PhantomReference can be used instead of a finalize method provided that the object is not resurrected during finalization. This allows the object to be garbage collected in a single cycle, rather than waiting for second garbage collection cycle to ensure that the object has not been resurrected.
A second use of phantom reference is to detect exactly when an object has been removed from memory (by using in combination with a ReferenceQueue object), ensuring that its memory is available, for example deferring allocation of a large amount of memory (e.g., a large image) until previous memory is freed (Wikipedia).
That’s all about strong, soft, weak and phantom references in Java programming language.
Thanks for reading.