[9] RFR (XS): 8169000: Define reference reachability more precisely in java.lang.ref package
David Holmes
david.holmes at oracle.com
Wed Nov 16 23:35:14 UTC 2016
On 17/11/2016 9:15 AM, Peter Levart wrote:
> Hi Zoltan,
>
>
> On 11/16/2016 10:27 PM, David Holmes wrote:
>> Peter has highlighted the risk with anything but the most minimal of
>> changes - the more you say the more likely you are saying something
>> that is incorrect. Reachability and the GC relationship to it is
>> extremely complex and can't be summarised in a few words.
>>
>> I would go back to the original simple suggestion to just add "detected":
>>
>> http://cr.openjdk.java.net/~zmajo/8169000/webrev.00
>>
>> "If a registered reference is detected as unreachable itself, then it
>> will never be enqueued."
>>
>> --
>>
>> That removes any expectation that you can determine whether or not it
>> will be unreachable based on looking at the source code or reasoning
>> about the bytecodes.
>
> Yes, but it also gives very little helpful information to a programmer.
>
> Why are we insisting in specifying when it is guaranteed for a Reference
> object to *not* be enqueued. This is not very helpful.
I disagree. The whole point of the statement was to make it clear that
for a referent to be enqueued the referee reference type must itself
remain reachable. The problem with the statement was that it could be
misconstrued as indicating when a referent _must_ not be enqueued.
> A more helpful information for a programmer would be to specify when a
> Reference object is guaranteed to *be* enqueued. Guarantee is given only
> if the Reference object is kept strongly reachable. If it ceases to be
> strongly reachable, it may never be enqueued, but it is not guaranteed
> that it will not be enqueued either.
>
> So this is still my favorite:
>
> "If a registered reference ceases to be strongly reachable for any
> period of time, it may become unreachable and never be enqueued. In
> order to guarantee for a registered reference to be enqueued, it must be
> kept strongly reachable at all times."
That seems redundant to me. Given the reachability definitions it
reduces to "If a registered reference becomes unreachable it may never
be enqueued."
David
-----
> Regards, Peter
>
>>
>> Cheers,
>> David
>> -----
>>
>>
>> On 17/11/2016 2:37 AM, Peter Levart wrote:
>>> 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