RFR (S) CR 6857566: (bf) DirectByteBuffer garbage creation can outpace reclamation
Peter Levart
peter.levart at gmail.com
Wed Oct 2 15:58:54 UTC 2013
Hi Aleksey,
I briefly skimmed over the changes. If I understand them correctly, they
change they way Cleaners are processed. Without any assistance from
other threads, Cleaners (WeakReferences now) are 1st enqueued by the
ReferenceHandler thread, and CleaningThread then picks them out of the
queue and processes them. Because they are not processed by
ReferenceHandler thread any more, cleaning does not interfere with
en-queueing of other References. This is good.
Assisting cleaning from other threads means that cleaning can be
performed in any thread. Cleaners should be prepared for that -
previously they were only invoked from ReferenceHandler thread.
assistCleanupSlow could really become slow, if lots of Cleaners get
allocated (for example, lots of small DirectByteBuffers get allocated)
and not GC-ed for some time.
This brings me to java.nio.Bits. It uses System.gc(). I understand that
allocation of native memory does not represent a memory pressure for
heap GC so you're trying to trigger it when it gets tight. But lots of
environments (app servers) are using -XX:+DisableExplicitGC to prevent
ill behaved libraries to trigger GCs to frequently. Have you tried your
test using -XX:+DisableExplicitGC ?
Regards, Peter
P.S.
I wish there was some Java-side API with which you could register (with
enough privilege) a filter that would decide whether to honour
System.gc() or not (making System.gc() @CallerSensitive and invoking a
registered Predicate<Class<?>>-s with the caller class, for example. If
any of registered Predicates returned true, the gc would be honoured).
App servers could use this API instead of -XX:+DisableExplicitGC then.
On 10/02/2013 04:43 PM, Aleksey Shipilev wrote:
> Hi,
>
> There is the issue that annoys me all the time:
> https://bugs.openjdk.java.net/browse/JDK-6857566
>
> Please review the rework of DirectByteBuffer cleanup mechanics fixing
> that issue. Since DBB uses sun.misc.Cleaner as the infrastructure to
> clean up things, we focus there:
> http://cr.openjdk.java.net/~shade/6857566/webrev.00/
>
> Brief explanation is there in Cleaner comments.
>
> Testing:
> - jtreg: jdk/nio tests on Linux x86_64/fastdebug
> - original sample test from 6857566, reproduces in a few seconds
> nicely with -XX:MaxDirectMemorySize=16M; more than 90 minutes run with
> patched build yield no OOMEs!
> - microbenchmarking, see below
>
> The microbenchmark tests allocates ByteBuffer.allocateDirect(N), with
> N=1,10,100,1000 bytes:
> http://cr.openjdk.java.net/~shade/6857566/directbb/
>
> On my 2x2 i5 Linux x86_64 laptop:
>
> Before patch (1 thread):
> direct_1 834 +- 159 ns/op
> direct_10 888 +- 262 ns/op
> direct_100 969 +- 307 ns/op
> direct_1000 1618 +- 46 ns/op
>
> Before patch (4 threads):
> direct_1 <OOME!>
> direct_10 <OOME!>
> direct_100 <OOME!>
> direct_1000 <OOME!>
>
> Single threaded allocators are working fine, but this means nothing,
> because more threads just plainly OOME.
>
> After patch (1 thread):
> direct_1 1645 +- 68 ns/op
> direct_10 1623 +- 53 ns/op
> direct_100 1704 +- 44 ns/op
> direct_1000 3327 +- 43 ns/op
>
> After patch (4 threads):
> direct_1 4673 +- 80 ns/op
> direct_10 4673 +- 114 ns/op
> direct_100 4771 +- 89 ns/op
> direct_1000 22310 +- 14390 ns/op
>
> Thanks,
> -Aleksey.
More information about the core-libs-dev
mailing list