RFR: 8344332: (bf) Migrate DirectByteBuffer to use java.lang.ref.Cleaner [v10]
Kim Barrett
kbarrett at openjdk.org
Wed Jan 29 19:32:09 UTC 2025
On Sat, 25 Jan 2025 07:14:51 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`
>> - [x] Linux x86_64 server fastdebug, `all`
>> - [x] Linux AArch64 server fastdebug, `all`
>
> Aleksey Shipilev has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 14 additional commits since the last revision:
>
> - Merge branch 'master' into JDK-8344332-dbb-cleaner
> - No instantiation for BufferCleaner, javadocs
> - Remove hasReferencePendingList
> - Revert test exclusion, moved to JDK-8348301
> - Alan's review
> - Remove vestigial reference to waitForReferenceProcessing in tests
> - Track Cleaner progress with canaries
> - Amend benchmarks
> - Fix tests
> - Review feedback and benchmarks
> - ... and 4 more: https://git.openjdk.org/jdk/compare/915b951b...bcfab1ba
src/java.base/share/classes/java/lang/ref/Reference.java line 282:
> 280: // references, or (2) the reference processing thread is
> 281: // processing references. Otherwise, returns false immediately.
> 282: private static boolean waitForReferenceProcessing()
Removing waitForReferenceProcessing is contrary to
https://bugs.openjdk.org/browse/JDK-8305186
Reference.waitForReferenceProcessing should be more accessible
I've pointed to JDK-8305186 in a number of discussions about problems encountered with various tests.
So I'm doubtful about removing it.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/22165#discussion_r1934462036
More information about the core-libs-dev
mailing list