RFR (S) CR 6857566: (bf) DirectByteBuffer garbage creation can outpace reclamation

Peter Levart peter.levart at gmail.com
Fri Oct 4 16:56:26 UTC 2013


On 10/04/2013 03:37 PM, Aleksey Shipilev wrote:
> Hi Peter,
>
> On 10/04/2013 04:43 PM, Peter Levart wrote:
>> >http://cr.openjdk.java.net/~plevart/jdk8-tl/Cleaners/webrev.02/
> So you are taking on assisting the ReferenceHandler directly. Nice idea.

Hi Aleksey,

I will go over your notes in a later followup. This time I present an 
even more refined and simple approach:

http://cr.openjdk.java.net/~plevart/jdk8-tl/Cleaners/webrev.03/

The trouble with previous approach was that while assisting 
ReferenceHandler thread and doing the cleaning synchronously "instead" 
of CleanerHandler thread (RQ.drain), the cleanersQueue was locked. If 
ReferenceHandler wanted to enqueue some Cleaner into cleanersQueue at 
that time, it would block and other Reference queueing would be 
impacted. So we're back to square-one when ReferenceHandler thread was 
processing Cleaners directly. Your approach doesn't have this problem.

So I devised another variant where we are helping ReferenceHandler but 
not with enqueue-ing. We're stealing Cleaners from the pending list in 
batches instead of going through trouble of enqueue-ing them one by one 
just to be able to de-queue them afterwards in the same thread. In order 
to prevent CleanerHandler from interfering while synchronous assistance 
is in progress (I really want to know when there're no more pending 
Cleaners - or at least when almost all of them have been processed - 
this is when I give-up and let Bits throw OOME), the CleanerHandler is 
paused by interrupting it.

Thread.sleep() can be inserted later between System.gc() and 
assistCleanup() if gc() happens to be asynchronous in some VM. The 
javadoc says the following:

/Calling the //|gc|//method suggests that the Java Virtual Machine 
expend effort toward recycling unused objects in order to make the 
memory they currently occupy available for quick reuse. When control 
returns from the method call, the Java Virtual Machine has made a best 
effort to reclaim space from all discarded objects. /

...this appears as synchronous to me and it behaves so in HotSpot. I'm 
just guessing, but I think that gc() triggers safepoint processing and 
waits for safepoint to begin. It only returns when safepoint is done and 
VM has already processed all references. But I don't know if that is 
guaranteed in all VMs.

Anyway, above variation is also predictable. I haven't been able to fail 
the test with any number of allocating threads.

Let me now go over your notes and see what still applies to this version...


Regards, Peter




More information about the core-libs-dev mailing list