RFR: 8071507: (ref) Clear phantom reference as soft and weak references do

Peter Levart peter.levart at gmail.com
Fri Dec 4 15:24:50 UTC 2015



On 12/04/2015 03:17 PM, Per Liden wrote:
> Hi Peter,
>
> On 2015-12-04 13:35, Peter Levart wrote:
>>
>>
>> On 12/04/2015 08:16 AM, Per Liden wrote:
>>>
>>> test/java/lang/ref/PhantomReferentClearing.java:
>>>
>>>   85         // Delete root -> O1, collect, verify P1 notified, P2 not
>>> notified.
>>>   86         O1 = null;
>>>   87         System.gc();
>>>   88         if (Q1.remove(ENQUEUE_TIMEOUT) == null) {
>>>   89             throw new RuntimeException("P1 not notified by O1
>>> deletion");
>>>   90         } else if (Q2.remove(ENQUEUE_TIMEOUT) != null) {
>>>   91             throw new RuntimeException("P2 notified by O1
>>> deletion.");
>>>   92         }
>>>   93
>>>   94         // Delete root -> O2, collect. P2 should be notified.
>>>   95         O2 = null;
>>>   96         System.gc();
>>>   97         if (Q2.remove(ENQUEUE_TIMEOUT) == null) {
>>>   98             throw new RuntimeException("P2 not notified by O2
>>> deletion");
>>>   99         }
>>>
>>> The calls to System.gc() isn't guaranteed to do what the test expects
>>> here. As you know, System.gc(), might not actually do anything,
>>> depending on which collector is used and the current circumstances (GC
>>> locker held, a concurrent GC is already in process, etc). To make the
>>> test robust I'd suggest you call System.gc() and check the queue in a
>>> loop, and fail after some reasonable amount of time/iterations.
>>
>> Whether you poll the queue for some time T or you remove from queue with
>> timeout of T, it doesn't matter. The Reference(s) are enqueued by a
>> ReferenceHandler thread and the thread waiting in remove() will get
>> notified when a reference gets enqueued...
>
> I think you maybe missed my point. There's no guarantee that a call to 
> System.gc() will cause reference processing to happen at all, and if 
> it happens there's no guarantee that it will discover P1/P2 here. In 
> this specific test it's very likely to happen, but that's a different 
> story. I still don't think this test should rely on a behavior that 
> isn't guaranteed by the spec.

Ah, you meant to call both System.gc() and queue.poll() in a loop. 
Sorry, I haven't understood you at first.

I agree that would be better. Short of System.gc(), is there anything 
else that could be used to trigger GC processing more reliably?

What about a loop that allocates until OOME is thrown and then releases 
everything so application can recover:

     static void triggerGC() {
         try {
             Object garbage = null;
             while(true) {
                 Object[] chunk = new Object[1<<16];
                 chunk[0] = garbage;
                 garbage = chunk;
             }
         } catch (OutOfMemoryError e) {
             // ignore
         }
     }


I think most GCs guarantee they run the GC before VM throws OOME.

Such test would have to be executed in othrevm with small heap: -Xmx16m 
or so...


Regards, Peter

>
> cheers,
> /Per
>
>>
>> Regards, Peter
>>
>>>
>>> cheers,
>>> /Per
>>>
>>>> http://cr.openjdk.java.net/~kbarrett/8071507/hotspot.05/
>>>>
>>>> Testing:
>>>> jprt, aurora ad hoc (defaults, GC/Runtime nightly, JCK)
>>>>
>>




More information about the hotspot-gc-dev mailing list