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









Reply via email to