Hi Peter, as discussed before in the other thread about move to jdk.internal: this looks fine to Apache Lucene. We have a separate issue to fix this for Java 9: https://issues.apache.org/jira/browse/LUCENE-6989
Currently the patch on the Lucene issue tries to cast the jdk.internal.Cleaner to Runnable; but with your patch, one would just need to cast to java.lang.ref.Cleaner$Cleanable (which is public anyways) and call clean(). The Runnable workaround was done for Lucene, Hadoop, and Netty, but with your current patch this extra hack will be obsolete: http://cr.openjdk.java.net/~chegar/8148117/src/java.base/share/classes/jdk/internal/ref/Cleaner.java.udiff.html So, I am fine with both solutions as workaround, if we can enforce unmapping - until an official and "safe" solution is found. I was discussing with Andrew Haley and Mark Reinhold on FOSDEM about an "official way" to unmap ByteBuffers and there seems to be a really cool idea to make MappedByteBuffer/DirectByteBuffer implement Closeable, so unmapping may work without the horrible performance degradion on every access by using some extra safepoint and changed volatile semantics using a annotation in Hotspot. Uwe ----- Uwe Schindler uschind...@apache.org ASF Member, Apache Lucene PMC / Committer Bremen, Germany http://lucene.apache.org/ > -----Original Message----- > From: core-libs-dev [mailto:core-libs-dev-boun...@openjdk.java.net] On > Behalf Of Peter Levart > Sent: Sunday, February 07, 2016 11:57 PM > To: Jeremy Manson <jeremyman...@google.com> > Cc: Core-Libs-Dev <core-libs-dev@openjdk.java.net> > Subject: Re: We don't need jdk.internal.ref.Cleaner any more > > > > On 02/07/2016 11:20 PM, Peter Levart wrote: > > > > > > On 02/07/2016 08:01 PM, Jeremy Manson wrote: > >> Hadoop seems to use sun.misc.Cleaner: > >> > >> > http://grepcode.com/file/repo1.maven.org/maven2/org.apache.hadoop/ha > doop-common/2.7.1/org/apache/hadoop/crypto/CryptoStreamUtils.java > >> > >> So you may want to keep it around transitionally (a la Unsafe). > > > > JEP 260 [1] was listing sun.misc.Cleaner as a critical API, but > > recently, it was decided to "hide" it away into jdk.internal.ref > > package which will not be exported [2]. The reasoning was this: > > > > "sun.misc.Cleaner ( was previously listed as a critical internal API, > > but on further investigation has been moved to an open issue, for the > > following reasons: 1) its primary use in the JDK is within NIO direct > > buffers to release native memory. The base module cannot have a > > dependency on jdk.unsupported so will need to be updated to use an > > alternative cleaner, 2) the usage of Cleaner outside the JDK, as > > determined by corpus analysis, has largely been observed to hack into > > private fields of the internal NIO direct buffer classes to explicitly > > release native memory. As stated in 1), the type of the cleaner used > > by NIO direct buffers will have to change. Given this, and the fact > > that JDK 9 has a new general purposed cleaner API, > > java.lang.ref.Cleaner, the value of keep sun.misc.Cleaner is > > questionable." > > > > If the decision to remove sun.misc.Cleaner was partly influenced by > > the desire to maintain just 2 instead of 3 Cleaner(s), then my > > proposal to migrate JDK code to the public API might enable Oracle to > > reconsider keeping sun.misc.Cleaner. > > OTOH, what hadoop is doing is exactly the usage described in the above > reasoning for removing sun.misc.Cleaner. > > Hadoop use case: > > public static void freeDB(ByteBuffer buffer) { > if (buffer instanceof sun.nio.ch.DirectBuffer) { > final sun.misc.Cleaner bufferCleaner = > ((sun.nio.ch.DirectBuffer) buffer).cleaner(); > bufferCleaner.clean(); > } > } > > can be rewritten using reflection to be compatible with either > sun.misc.Cleaner (on JDK 8 or less) or java.lang.ref.Cleaner$Cleanable > (on JDK 9 or more): > > static final Method cleanMethod; > > static { > try { > Class<?> cleanerOrCleanable; > try { > cleanerOrCleanable = Class.forName("sun.misc.Cleaner"); > } catch (ClassNotFoundException e1) { > try { > cleanerOrCleanable = > Class.forName("java.lang.ref.Cleaner$Cleanable"); > } catch (ClassNotFoundException e2) { > e2.addSuppressed(e1); > throw e2; > } > } > cleanMethod = cleanerOrCleanable.getDeclaredMethod("clean"); > } catch (Exception e) { > throw new Error(e); > } > } > > public static void freeDB_JDK8or9(ByteBuffer buffer) { > if (buffer instanceof sun.nio.ch.DirectBuffer) { > final Object bufferCleaner = > ((sun.nio.ch.DirectBuffer) buffer).cleaner(); > > try { > if (bufferCleaner != null) { > cleanMethod.invoke(bufferCleaner); > } > } catch (InvocationTargetException | IllegalAccessException > e) { > throw new Error(e); > } > } > } > > > I thought about this use case and even kept the name of the method on > sun.nio.ch.DirectBuffer::cleaner to make things easier although the > return type in my patched DirectBufer is called > java.lang.ref.Cleaner$Cleanable. > > > Regards, Peter > > > > > [1] https://bugs.openjdk.java.net/browse/JDK-8132928 > > [2] https://bugs.openjdk.java.net/browse/JDK-8148117 > > > > Regards, Peter > > > >> > >> Jeremy > >> > >> On Sun, Feb 7, 2016 at 2:53 AM, Peter Levart <peter.lev...@gmail.com > >> <mailto:peter.lev...@gmail.com>> wrote: > >> > >> Hi, > >> > >> sun.misc.Cleaner has been moved to internal package > >> jdk.internal.ref recently [1] to clean-up sun.misc namespace. But > >> now that: > >> > >> - we have comparable public API (java.lang.ref.Cleaner & > >> Cleanable) [2] > >> - we have an internal shared java.lang.ref.Cleaner instance > >> (jdk.internal.ref.CleanerFactory.cleaner()) > >> - sun.misc.Cleaner is not a special kind of Reference any more in > >> the JVM [3] > >> > >> ...I think there's no reason to keep this special internal API > >> any more. It can be replaced with public API. > >> > >> I propose to remove jdk.internal.ref.Cleaner class and replace > >> its usages with java.lang.ref.Cleaner and friends [4]. > >> > >> What do you say? > >> > >> Regards, Peter > >> > >> > >> [1] https://bugs.openjdk.java.net/browse/JDK-8148117 > >> [2] https://bugs.openjdk.java.net/browse/JDK-8138696 > >> [3] https://bugs.openjdk.java.net/browse/JDK-8143847 > >> [4] > >> http://cr.openjdk.java.net/~plevart/jdk9- > dev/removeInternalCleaner/webrev.01/ > >> <http://cr.openjdk.java.net/%7Eplevart/jdk9- > dev/removeInternalCleaner/webrev.01/> > >> > >> > >> > >> > >> > >> > >> > >