Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace access to sun.misc.VM for JDK 11

Tags:

java

java-11

In OpenJDK 8, it was possible to access sun.misc.VM and call isDirectMemoryPageAligned and maxDirectMemory.
isDirectMemoryPageAligned is used to size correctly the direct memory to allocate, as done by DirectByteBuffer.
maxDirectMemory is used to report memory statistics as well as access giving the value configured for -XX:MaxDirectMemorySize. Internally, it will set a limit to the allowed consumption of direct memory.

Since OpenJDK 9, the class VM has been moved to jdk.internal.misc and is not available unless --add-export java.base/jdk.internal.misc=xyz is used when running the application.

Is there a "right" way to do this ?

I already tried to use ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getMax() as a replacement for maxDirectMemory but it always returned -1 - meaning that the value was not available. It is also possible to access java.nio.Bits#MAX_MEMORY by reflection, but it remains "hackish".


Note that one could be very very dirty and do the following - working for OpenJDK, Zulu and Oracle 11.0.1 - but it is not the target goal of this question.

public static void tryExportInternal() {
    final String moduleName = "jdk.internal.misc";
    final Module javaLang = Integer.class.getModule();

    // Method used only for tests by the JDK...
    final Method exporter;
    try {
        exporter = Module.class.getDeclaredMethod("implAddExports", String.class);
        exporter.setAccessible(true);
        exporter.invoke(javaLang, moduleName);
    } catch (NoSuchMethodException | IllegalAccessException e) {
        LOG.log(Level.INFO, "Cannot access internal Module method", e);
    } catch (InvocationTargetException e) {
        LOG.log(Level.INFO, "Cannot call internal Module method", e);
    }
}

In the source code, implAddExports is marked as @apiNote This method is for JDK tests only. :(

like image 976
Kineolyan Avatar asked Nov 29 '18 16:11

Kineolyan


People also ask

What was removed in Java 11?

In JDK 11, the Java EE and CORBA modules were removed. These modules were deprecated for removal in JDK 9. The removed modules are: java.xml.ws: Java API for XML Web Services (JAX-WS), Web Services Metadata for the Java Platform, and SOAP with Attachments for Java (SAAJ)

Is Java 11 fully backward compatible with Java 8?

Java 11 is backwards compatible with Java 8. So you can swiftly change from Java 8 to 11.

Does Jdk 11 release offer separate JRE?

In JDK 11, this is no longer an option. In this release, the JRE or Server JRE is no longer offered. Only the JDK is offered. Users can use jlink to create smaller custom runtimes.


1 Answers

This answer comes from the various comments of Alan Bateman to the question.

No, there are no standard API to access the two wanted methods.

Since JDK 6, DirectxxxBuffers are not paged aligned anymore. Thus, accessing VM.isDirectMemoryPageAligned is not needed to reproduce what DirectBuffers do.


About manually memory allocation, being the use-case behind the question, the only API to do direct memory allocation is currently ByteBuffer.allocateDirect, or its JNI alternative NewDirectByteBuffer.


Comment references: 1 2 3

like image 95
Kineolyan Avatar answered Oct 13 '22 02:10

Kineolyan