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.

Reply via email to