On 9/27/17 10:55 AM, Hans Boehm wrote:
"And of course, it guarantees that the tracked referent can not be
resurrected as a result of cleanup code execution."

True, but it seems to me that the real property you want is "it guarantees
that the tracked referent can not be resurrected". Full stop. Actually, the
property I really need is: "The referent of an enqueued PhantomReference
cannot subsequently be accessed."

Unfortunately, neither of those last two appear to be true due to the
weakly specified behavior of JNI WeakGlobalRefs. The spec says:

"Interactions between weak global references and PhantomReferences are
undefined. In particular, implementations of a Java VM may (or may not)
process weak global references after PhantomReferences, and it may (or may
not) be possible to use weak global references to hold on to objects which
are also referred to by PhantomReference objects. This undefined use of
weak global references should be avoided."

This allows a WeakGlobalRef to be converted to a strong JNI ref after a
PhantomReference to the same object has been enqueued, thus resurrecting
the referent, and allowing access.

The advice in the last sentence seems to be both essential and completely
impractical, since the WeakGlobalRef may point to another object, which may
then indirectly point ot the PhantomReference referent. Hence you can't
prevent this interaction without global, whole program knowledge of which
objects may indirectly reference PhantomReference referents. This is
essentially the same problem we had with (unordered) finalization, only now
confined to programs that use WeakGlobalRefs.

Am I reading this correctly? Is it intended? It seems like it should be
fixable by giving WeakGlobalRefs essentially WeakReference behavior, as the
name implies?


Thanks for pointing this out.   I create a JBS issue to follow up this:
   https://bugs.openjdk.java.net/browse/JDK-8188066

Mandy

Reply via email to