Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 替换对JDK 11的sun.misc.VM的访问_Java_Java 11 - Fatal编程技术网

Java 替换对JDK 11的sun.misc.VM的访问

Java 替换对JDK 11的sun.misc.VM的访问,java,java-11,Java,Java 11,在OpenJDK 8中,可以访问sun.misc.VM并调用isDirectMemoryPageAligned和maxDirectMemory isDirectMemoryPageAligned用于正确调整要分配的直接内存的大小,如所做。 maxDirectMemory用于报告内存统计信息,以及提供为-XX:MaxDirectMemorySize配置的值的访问。在内部,它将对直接内存的允许消耗设置一个限制 自OpenJDK 9以来,类VM已被移动到jdk.internal.misc,并且不可用,

在OpenJDK 8中,可以访问
sun.misc.VM
并调用
isDirectMemoryPageAligned
maxDirectMemory

isDirectMemoryPageAligned
用于正确调整要分配的直接内存的大小,如所做。
maxDirectMemory
用于报告内存统计信息,以及提供为
-XX:MaxDirectMemorySize
配置的值的访问。在内部,它将对直接内存的允许消耗设置一个限制

自OpenJDK 9以来,类VM已被移动到jdk.internal.misc,并且不可用,除非在运行应用程序时使用
--add export java.base/jdk.internal.misc=xyz

有没有“正确”的方法

我已经尝试使用
ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getMax()
替换
maxDirectMemory
,但它始终返回-1-表示该值不可用。也可以通过反射访问
java.nio.Bits#MAX_内存
,但它仍然是“黑客式的”


请注意,一个可能非常脏,并执行以下操作-为OpenJDK、Zulu和Oracle 11.0.1工作-但这不是这个问题的目标

在源代码中,
impladexports
标记为
@apiNote此方法仅用于JDK测试
:(

这个答案来自对这个问题的各种评论

不,没有标准API来访问这两个想要的方法

自JDK 6以来,DirectxxxBuffers不再分页对齐。因此,不需要访问VM.isDirectMemoryPageAligned来重现DirectBuffers的功能


关于手动内存分配,作为问题背后的用例,目前唯一进行直接内存分配的API是
ByteBuffer.allocateDirect
,或其JNI替代方案
NewDirectByteBuffer



注释引用:

您测试过@VGR吗?如果是,请向我报告您使用的VM。我将尝试找出原因。这里的诀窍是使用动态等效的
--add exports
,这是使用java.lang.Module的私有方法和反射来完成的。请参阅问题中包含的hack是可怕的,c任何时候都会中断。几个版本的直接缓冲区都没有进行页面对齐,所以现在不清楚为什么需要这样做。也需要关于-XX:MaxDirectMemorySize=值的更多信息。自JDK 6以来,缓冲区没有进行页面对齐。没有支持的接口来说明为什么需要这样做为什么不直接调用ByteBuffer.allocateDirect?如果您自己分配内存,那么您可以使用JNI的NewDirectByteBuffer将该区域包装为直接缓冲区,也许这就是您要寻找的。
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);
    }
}