Java 替换对JDK 11的sun.misc.VM的访问
在OpenJDK 8中,可以访问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,并且不可用,
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);
}
}