将 sun.misc.VM 的访问权限替换为 JDK 11
Replace access to sun.misc.VM for JDK 11
在 OpenJDK 8 中,可以访问 sun.misc.VM
并调用 isDirectMemoryPageAligned
和 maxDirectMemory
。
isDirectMemoryPageAligned
用于正确调整要分配的直接内存的大小,如 DirectByteBuffer 所做的那样。
maxDirectMemory
用于报告内存统计信息以及为 -XX:MaxDirectMemorySize
配置的值的访问。在内部,它将对允许的直接内存消耗设置限制。
自 OpenJDK 9 起,class VM 已移至 jdk.internal.misc,除非在 运行 应用程序。
有没有 "right" 方法来做到这一点?
我已经尝试使用 ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getMax()
替代 maxDirectMemory
但它总是返回 -1 - 意味着该值不可用。也可以通过反射访问 java.nio.Bits#MAX_MEMORY
,但它仍然是“hackish”。
请注意,可能非常非常脏并执行以下操作 - 适用于 OpenJDK、Zulu 和 Oracle 11.0.1 - 但这不是此问题的目标。
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);
}
}
在源代码中,implAddExports
被标记为@apiNote This method is for JDK tests only
。 :(
此答案来自Alan Bateman对问题的各种评论。
不,没有标准API来访问这两个想要的方法。
自 JDK6 起,DirectxxxBuffers 不再进行分页对齐。因此,不需要访问 VM.isDirectMemoryPageAligned
来重现 DirectBuffers 的功能。
关于手动内存分配,作为问题背后的用例,目前唯一 API 进行直接内存分配的是 ByteBuffer.allocateDirect
,或其 JNI 替代方案 NewDirectByteBuffer
。
评论参考:
在 OpenJDK 8 中,可以访问 sun.misc.VM
并调用 isDirectMemoryPageAligned
和 maxDirectMemory
。
isDirectMemoryPageAligned
用于正确调整要分配的直接内存的大小,如 DirectByteBuffer 所做的那样。
maxDirectMemory
用于报告内存统计信息以及为 -XX:MaxDirectMemorySize
配置的值的访问。在内部,它将对允许的直接内存消耗设置限制。
自 OpenJDK 9 起,class VM 已移至 jdk.internal.misc,除非在 运行 应用程序。
有没有 "right" 方法来做到这一点?
我已经尝试使用 ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getMax()
替代 maxDirectMemory
但它总是返回 -1 - 意味着该值不可用。也可以通过反射访问 java.nio.Bits#MAX_MEMORY
,但它仍然是“hackish”。
请注意,可能非常非常脏并执行以下操作 - 适用于 OpenJDK、Zulu 和 Oracle 11.0.1 - 但这不是此问题的目标。
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);
}
}
在源代码中,implAddExports
被标记为@apiNote This method is for JDK tests only
。 :(
此答案来自Alan Bateman对问题的各种评论。
不,没有标准API来访问这两个想要的方法。
自 JDK6 起,DirectxxxBuffers 不再进行分页对齐。因此,不需要访问 VM.isDirectMemoryPageAligned
来重现 DirectBuffers 的功能。
关于手动内存分配,作为问题背后的用例,目前唯一 API 进行直接内存分配的是 ByteBuffer.allocateDirect
,或其 JNI 替代方案 NewDirectByteBuffer
。
评论参考: