We don't need jdk.internal.ref.Cleaner any more
Peter Levart
peter.levart at gmail.com
Sun Feb 7 22:57:02 UTC 2016
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.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