[9] RFR (XS): 8169000: Define reference reachability more precisely in java.lang.ref package
Peter Levart
peter.levart at gmail.com
Wed Nov 16 16:37:33 UTC 2016
Hi,
On 11/16/2016 05:09 PM, Peter Levart wrote:
>>
>> http://cr.openjdk.java.net/~zmajo/8169000/webrev.03/
>
> "If a registered reference ceases to be strongly reachable itself (not
> by examining the source code but by looking at the actual state of the
> VM at runtime), it will never be enqueued."
>
> I think this is wrong wording. A Reference object may cease to be
> strongly reachable for some time (even by looking at the actual state
> of the VM at runtime) and then regain strong reachability and then be
> enqueued. If during the period that a Reference object is not strongly
> reachable (even by looking at the actual state of the VM at runtime),
> GC is not run, the Reference object will not be discovered as not
> being strongly reachable and VM will not clear any Soft or Weak
> references having the Reference object as a referent and consequently
> the program will be able to regain strong reachability to it.
A counter example: A Reference object may cease to be strongly reachable
by becoming softly reachable. The JVM may even discover it to be softly
reachable (looking at the actual state of the VM at runtime), but by
policy, VM may also see that is has not been softly reachable long
enough and so it will not clear the SoftReference but instead rather
enqueue the SoftReference's referent (our PhantomReference object):
public class SoftlyReachablePhantomReference {
static ReferenceQueue<Object> rq = new ReferenceQueue<>();
static Reference<PhantomReference<Object>> refRef;
public static void main(final String[] args) throws Exception {
refRef = new SoftReference<>(
new PhantomReference<>(
new Object(),
rq
)
);
// <- here
System.gc();
Reference rmRef = rq.remove(1000);
if (rmRef == null) {
System.out.println("PhantomReference NOT enqueued");
} else {
System.out.println("PhantomReference enqueued");
}
}
}
Running with -Xcomp, the above program will print: "PhantomReference
enqueued". By just swapping SoftRererence with WeakReference:
public class WeaklyReachablePhantomReference {
static ReferenceQueue<Object> rq = new ReferenceQueue<>();
static Reference<PhantomReference<Object>> refRef;
public static void main(final String[] args) throws Exception {
refRef = new WeakReference<>(
new PhantomReference<>(
new Object(),
rq
)
);
// <- here
System.gc();
Reference rmRef = rq.remove(1000);
if (rmRef == null) {
System.out.println("PhantomReference NOT enqueued");
} else {
System.out.println("PhantomReference enqueued");
}
}
}
...the program will print: "PhantomReference NOT enqueued".
This is all expected and by the spec.
Peter
More information about the core-libs-dev
mailing list