In his answer to a related question about the behavior of a PhantomReference
when the queue is given as null
, Holger says this:
"The question, even harder to answer, is why a PhantomReference
isn’t automatically cleared. The documentation only says that a phantom reachable object will remain so, which is the consequence of not being cleared, but doesn’t explain why this has any relevance.
This question has been brought up on SO, but the answer isn’t really satisfying. It says “to allow performing cleanup before an object is garbage collected”, which might even match the mindset of whoever made that design decision, but since the cleanup code can’t access the object, it has no relevance whether it is executed before or after the object is reclaimed. As said above, since this rule depends on the reachability of the PhantomReference
object, which is subject to optimizing code transformations, it might be even the case that the object is reclaimed together with the PhantomReference
instance before the cleanup code completes, without anyone noticing.
I also found a similar question on the HotSpot developer mailing list back in 2013 which also lacks an answer.
There is the enhancement request JDK-8071507 to change that behavior and clear PhantomReferences
just like the others, which has the status “fixed” for Java 9, and indeed, the javadocs now state that they are cleared like any other reference."
In summary:
- The original design decision to not clear the reference was questionable.
- The behavior has changed, as of Java 9.
However you asked your question like this:
So why JVM waits for a manual clear()
?
Strictly speaking, the JVM waits for either a manual clear, or for the PhantomReference
itself to become unreachable. (As Holger said above.)
So it is not quite as bad (in Java 8 and earlier) as your question would imply.