RFR: 8344332: (bf) Migrate DirectByteBuffer to use java.lang.ref.Cleaner [v4]
Aleksey Shipilev
shade at openjdk.org
Tue Jan 21 09:46:58 UTC 2025
On Mon, 20 Jan 2025 19:12:22 GMT, Aleksey Shipilev <shade at openjdk.org> wrote:
>> DirectByteBuffers are still using old `jdk.internal.ref.Cleaner` implementation. That implementation carries a doubly-linked list, and so makes DBB suffer from the same issue fixed for generic `java.lang.ref.Cleaner` users with [JDK-8343704](https://bugs.openjdk.org/browse/JDK-8343704). See the bug for the reproducer.
>>
>> We can migrate DBBs to use `java.lang.ref.Cleaner`.
>>
>> There are two pecularities during this rewrite.
>>
>> First, the old ad-hoc `Cleaner` implementation used to exit the VM when cleaning action failed. I presume it was to avoid memory leak / accidental reuse of the buffer. I moved the relevant block to `Deallocator` directly. Unfortunately, I cannot easily test it.
>>
>> Second is quite a bit hairy. Old DBB cleaning code was hooked straight into `Reference` processing loop. This was possible because we could infer that the weak references we are processing were DBB cleaning actions, since old `Cleaner` was the only use of this code. With standard `Cleaner`, we have lost this association, and so we cannot really do this from the reference processing loop. With the patched version, we now rely on normal `Cleaner` thread to do cleanups for us. Because of this, there is a new outpacing opportunity window where reference processing might have been over, but cleaner thread has not reacted yet.
>>
>> Tests show that DirectBufferAlloc tests are still surviving this, possibly due to exponential sleep-backoff already built in. See the reclamation path in `Bits.unreserveMemory`: https://github.com/openjdk/jdk/blob/c207cc7e705d3f449f2387324d86cfb31ce40c44/src/java.base/share/classes/java/nio/Bits.java#L106-L186
>>
>> Additional testing:
>> - [x] Linux x86_64 server fastdebug, `java/nio java/io`
>> - [x] Linux AArch64 server fastdebug, `java/nio java/io`
>> - [ ] Linux x86_64 server fastdebug, `all`
>> - [ ] Linux AArch64 server fastdebug, `all`
>
> Aleksey Shipilev has updated the pull request incrementally with one additional commit since the last revision:
>
> Review feedback and benchmarks
Benchmark data on new benchmarks:
Benchmark (count) (recipFreq) Mode Cnt Score Error Units
# Before
DirectByteBufferChurn.test N/A 128 avgt 9 11.852 ± 0.505 ns/op
DirectByteBufferChurn.test N/A 256 avgt 9 9.107 ± 0.695 ns/op
DirectByteBufferChurn.test N/A 512 avgt 9 7.643 ± 0.480 ns/op
DirectByteBufferChurn.test N/A 1024 avgt 9 7.091 ± 0.183 ns/op
DirectByteBufferChurn.test N/A 2048 avgt 9 6.734 ± 0.184 ns/op
DirectByteBufferGC.test 16384 N/A avgt 9 3.122 ± 0.028 ms/op
DirectByteBufferGC.test 65536 N/A avgt 9 6.079 ± 0.111 ms/op
DirectByteBufferGC.test 262144 N/A avgt 9 16.892 ± 0.705 ms/op
DirectByteBufferGC.test 1048576 N/A avgt 9 156.980 ± 9.673 ms/op
DirectByteBufferGC.test 4194304 N/A avgt 9 725.576 ± 49.363 ms/op
# After
DirectByteBufferChurn.test N/A 128 avgt 9 8.697 ± 0.742 ns/op ; <---
DirectByteBufferChurn.test N/A 256 avgt 9 7.557 ± 0.353 ns/op ; <---
DirectByteBufferChurn.test N/A 512 avgt 9 7.074 ± 0.268 ns/op ; <---
DirectByteBufferChurn.test N/A 1024 avgt 9 6.853 ± 0.272 ns/op
DirectByteBufferChurn.test N/A 2048 avgt 9 6.688 ± 0.298 ns/op
DirectByteBufferGC.test 16384 N/A avgt 9 3.197 ± 0.231 ms/op
DirectByteBufferGC.test 65536 N/A avgt 9 5.442 ± 0.323 ms/op
DirectByteBufferGC.test 262144 N/A avgt 9 16.967 ± 0.485 ms/op
DirectByteBufferGC.test 1048576 N/A avgt 9 50.613 ± 2.107 ms/op ; <---
DirectByteBufferGC.test 4194304 N/A avgt 9 343.177 ± 20.655 ms/op ; <---
-------------
PR Comment: https://git.openjdk.org/jdk/pull/22165#issuecomment-2604187764
More information about the nio-dev
mailing list