RFR: 8344332: (bf) Migrate DirectByteBuffer away from jdk.internal.ref.Cleaner [v3]

Kim Barrett kbarrett at openjdk.org
Wed May 21 02:36:16 UTC 2025


> This change makes java.nio no longer use jdk.internal.ref.Cleaner to manage
> native memory for Direct-X-Buffers. Instead it uses bespoke PhantomReferences
> and a dedicated ReferenceQueue. This differs from PR 22165, which proposed to
> use java.lang.ref.Cleaner.
> 
> This change is algorithmically similar to the two previous versions:
> JDK-6857566 and JDK-8156500 (current mainline). The critical function is
> Bits::reserveMemory(). For both of those versions and this change, a thread
> calls that function and tries to reserve some space. If it fails, then it
> keeps trying until all cleaners deactivated (cleared) by prior GCs have been
> cleaned. If reservation still fails, then it invokes the GC to try to
> deactivate more cleaners for cleaning. After that GC it keeps trying the
> reservation and waiting for cleaning, with sleeps to avoid a spin loop,
> eventually either succeeding or giving up and throwing OOME.
> 
> Retaining that algorithmic approach is one of the goals of this change, since
> it has been successfully in use since JDK 9 (and was originally developed and
> extensively tested in JDK 8).
> 
> The key to this approach is having a way to determine that deactivated
> cleaners have been cleaned. JDK-6857566 accomplished this by having waiting
> threads help the reference processor until there was no available work.
> JDK-8156500 waits for the reference processor to quiesce, relying on its
> immediate processing of cleaners. java.lang.ref.Cleaner doesn't provide a way
> to do this, which is why this change rolls its own Cleaner-like mechanism from
> the underlying primitives. Like JDK-6857566, this change has waiting threads
> help with cleaning references. This was a potentially undesirable feature of
> JDK-6857566, as arbitrary allocating threads were invoking arbitrary cleaners.
> (Though by the time of JDK-6857566 the cleaners were only used by DBB, and
> became internal-only somewhere around that time as well.) That's not a concern
> here, as the cleaners involved are only from DBB, and we know what they look
> like.
> 
> As noted in the discussion of JDK-6857566, it's good to have DBB cleaning
> being done off the reference processing thread, as it may be expensive and
> slow down enqueuing other pending references. JDK-6857566 only did some of
> that, and JDK-8156500 lost that feature. This change moves all of the DBB
> cleaning off of the reference processing thread. (So does PR 22165.)
> 
> Neither JDK-6857566 nor this change are completely precise. For both, a thread
> may find there is no available work whil...

Kim Barrett has updated the pull request incrementally with three additional commits since the last revision:

 - add description of BufferCleaner class
 - exception handling in cleaner for backward consistency
 - detabify

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/25289/files
  - new: https://git.openjdk.org/jdk/pull/25289/files/45d0b1ef..be3312cb

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=25289&range=02
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25289&range=01-02

  Stats: 40 lines in 2 files changed: 28 ins; 8 del; 4 mod
  Patch: https://git.openjdk.org/jdk/pull/25289.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/25289/head:pull/25289

PR: https://git.openjdk.org/jdk/pull/25289


More information about the core-libs-dev mailing list