We don't need jdk.internal.ref.Cleaner any more
Uwe Schindler
uschindler at apache.org
Sun Feb 7 23:25:21 UTC 2016
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
uschindler at apache.org
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/
> -----Original Message-----
> From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On
> Behalf Of Peter Levart
> Sent: Sunday, February 07, 2016 11:57 PM
> To: Jeremy Manson <jeremymanson at google.com>
> Cc: Core-Libs-Dev <core-libs-dev at 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.levart at gmail.com
> >> <mailto:peter.levart at 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/>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >
More information about the core-libs-dev
mailing list