Last active
March 29, 2018 07:26
-
-
Save KowalczykBartek/991bf9022dc2b212d24fc9c8f5298404 to your computer and use it in GitHub Desktop.
Some notes about WeakReference SoftReference and PhantomReference in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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