Skip to content

Instantly share code, notes, and snippets.

@KowalczykBartek
Last active March 29, 2018 07:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KowalczykBartek/991bf9022dc2b212d24fc9c8f5298404 to your computer and use it in GitHub Desktop.
Save KowalczykBartek/991bf9022dc2b212d24fc9c8f5298404 to your computer and use it in GitHub Desktop.
Some notes about WeakReference SoftReference and PhantomReference in Java
/*
If you were looking for information about Weak/Soft or Phantom references, you probably found this blog post
https://web.archive.org/web/20061130103858/http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html
This is great piece of knowledge, but there is one statement that not necessarily is true.
Lets consider this paragraph in context of Java 7/8
"PhantomReferences are enqueued only when the object is physically removed from memory,
and the get() method always returns null specifically to prevent you from being able to "resurrect" an almost-dead object."
This is true that get() method of PhantomReference always returns null, but this is not true that object is enqueued only
when it is physically removed - on the contrary, object will be removed but first it has to be enqueued and ... you have to
explicitly call .clear() method of reference received from ReferenceQueue - only then, GC can saftly remove object from memory.
What with Java 9 ? In Java9 PhantomReference becomes automatically-cleared reference (compare https://docs.oracle.com/javase/8/docs/api/java/lang/ref/PhantomReference.html
and https://docs.oracle.com/javase/9/docs/api/java/lang/ref/PhantomReference.html),
you can check relevant JIRA ticket for that enhancement (https://bugs.openjdk.java.net/browse/JDK-8071507).
One thing more - I was always curious what means that SoftReference "is less eager to throw away the object to which it refers"
than WeakReference. Because I am afraid of C/C++ - looking at the source code of specyfic JVM is quite dificult, but thanks
to https://wiki.openjdk.java.net/display/HotSpot/The+WhiteBox+testing+API we can play aroung Young GC and Full GC :)
lets write some code :)
*/
WhiteBox whiteBox = WhiteBox.getWhiteBox();
String object = new String("I'm a lonely piece of garbage.");a
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
Reference<String> reference = new SoftReference<>(object, referenceQueue);
object = null;
System.err.println("reference.get = " + reference.get());
whiteBox.youngGC();
Reference poll = referenceQueue.poll();
System.err.println("reference.get = " + reference.get());
System.err.println("referenceQueue.poll = " + poll);
/*
SoftReference was able to survive young GC in my all tests, calling fullGC on whiteBox always caused Reference to be cleared,
enqueuing was less predictable - (so, for example, SoftReference was clear, returned null on its get() method, but was not yet enqueued)
Comparing SoftReference with WeakReference - WeakReference is cleared even by whiteBox.youngGC, and this really looks like
SoftReference is less eager to be cleared by GC :)
I encourage to play around WhiteBox because it is really cool API for JVM internals.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment