Understanding Java's Reference classes: SoftReference, WeakReference, and PhantomReference
Solution 1
The Java library documentation for the java.lang.ref
package characterizes the decreasing strength of the three explicit reference types.
You use a SoftReference
when you want the referenced object to stay alive until the host process is running low on memory. The object will not be eligible for collection until the collector needs to free memory. Loosely stated, binding a SoftReference
means, "Pin the object until you can't anymore."
By contrast, use a WeakReference
when you don't want to influence the referenced object's lifetime; you merely want to make a separate assertion about the referenced object, so long as it remains alive. The object's eligibility for collection is not influenced by the presence of bound WeakReference
s. Something like an external mapping from object instance to related property, where the property need only be recorded so long as the related object is alive, is a good use for WeakReference
s and WeakHashMap
.
The last one—PhantomReference
—is harder to characterize. Like WeakReference
, such a bound PhantomReference
exerts no influence on the referenced object's lifetime. But unlike the other reference types, one can't even dereference a PhantomReference
. In a sense, it doesn't point to the thing it points to, as far as callers can tell. It merely allows one to associate some related data with the referenced object—data that can later be inspected and acted upon when the PhantomReference
gets queued in its related ReferenceQueue
. Normally one derives a type from PhantomReference
and includes some additional data in that derived type. Unfortunately, there's some downcasting involved to make use of such a derived type.
In your example code, it's not the ref
reference (or, if you prefer, "variable") that can be null. Rather, it's the value obtained by calling Reference#get()
that may be null. If it is found to be null, you're too late; the referenced object is already on its way to being collected:
final String val = ref.get();
if (null != val)
{
// "val" is now pinned strongly.
}
else
{
// "val" is already ready to be collected.
}
Solution 2
A link: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap
wouldn't work very well as get
always returns null
for phantom references.
Caches are difficult, so SoftHashMap
might not work as well as you might think. However, I believe Google's collection library contains a general reference map implementation.
You should always check that get
returns non-null
. (Note, that not checking that the Reference
reference itself is not-null
.) In the case of interned strings it always will, but (as ever) don't try to be "clever" about it.
Solution 3
It should also be mentioned, as stated on the comment by Truong Xuan Tinh, here: http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/
That JRockit JVM implements weak/soft/phantom references differently than Sun JVM.
Related videos on Youtube
Haywood Jablomey
Updated on July 05, 2022Comments
-
Haywood Jablomey almost 2 years
Can someone explain the difference between the three Reference classes (or post a link to a nice explanation)?
SoftReference
>WeakReference
>PhantomReference
, but when would I use each one? Why is there aWeakHashMap
but noSoftHashMap
orPhantomHashMap
?And if I use the following code...
WeakReference<String> ref = new WeakReference<String>("Hello!"); if (ref != null) { // ref can get collected at any time... System.gc(); // Let's assume ref gets collected here. System.out.println(ref.get()); // Now what?! }
...what happens? Do I have to check if
ref
is null before every statement (this is wrong, but what should I do)? Sorry for the rapid-fire questions, but I'm having trouble understanding theseReference
classes... Thanks!-
Mehraj Malik over 6 yearsWhy is there a
WeakHashMap
but noSoftHashMap
orPhantomHashMap
Excellent question, why I did not noticed this before..?? -
Holger almost 4 yearsThe
ref != null
check makes no sense.ref
will never benull
. -
samshers almost 4 yearsadding to the Q:
strongRef --> weakRef --> objA
. Now, willobjA
will be GCed or not, as it has an indirect ref fromstrongRef
.
-
-
Mehraj Malik over 6 yearsThe link has expired.
-
Brett over 6 years@MehrajMalik Link fixed.
-
samshers almost 4 yearsadding to the Q:
strongRef --> weakRef --> objA
. Now, willobjA
will be GCed or not, as it has an indirect ref fromstrongRef
. -
samshers almost 4 yearsadding to the Q:
strongRef --> weakRef --> objA
. Now, willobjA
will be GCed or not, as it has an indirect ref fromstrongRef
. -
subrat71 almost 4 yearsIf I understand your question correctly, @samshers,
objA
is eligible for collection as garbage. Pinning aWeakReference
exerts no influence over the object to which thatWeakReference
points. -
samshers almost 4 yearsDoes not having a strong reference up the chain make difference. Because for the
objA
to be garbage collected the weak reference has to be removed first right. And a strong reference is pointing to the weak reference making the weak ref ineligible to be GCed -
subrat71 almost 4 yearsNo, the
WeakReference
does not need to be collected in order to allowobjA
to be collected. TheWeakReference
does not keepobjA
alive. Rather, it is a way to findobjA
while it's alive—without influencing that lifetime—and detect when the collector already took it away.