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/hadoop-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/>