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 core-libs-dev
mailing list