替换对JDK 11的sun.misc.VM的访问 [英] Replace access to sun.misc.VM for JDK 11

查看:512
本文介绍了替换对JDK 11的sun.misc.VM的访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在OpenJDK 8中,可以访问sun.misc.VM并调用isDirectMemoryPageAlignedmaxDirectMemory.
isDirectMemoryPageAligned用于正确调整要分配的直接内存的大小,如

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.

自OpenJDK 9起,类VM已移至 jdk.internal.misc ,除非运行应用程序时使用--add-export java.base/jdk.internal.misc=xyz,否则该类VM不可用.

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 ?

我已经尝试使用ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getMax()代替maxDirectMemory,但是它总是返回-1-表示该值不可用.也可以通过反射方式访问java.nio.Bits#MAX_MEMORY,但它仍为" hackish ".

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".

请注意,可能非常肮脏,并且需要执行以下操作-适用于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.:(

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

推荐答案

此答案来自艾伦·贝特曼(Alan Bateman)提问.

不,没有标准的API可以访问这两种通缉方法.

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

自JDK 6起,DirectxxxBuffer不再分页对齐.因此,不需要访问VM.isDirectMemoryPageAligned即可重现DirectBuffer的功能.

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

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

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.

注释参考: 1 2 3

这篇关于替换对JDK 11的sun.misc.VM的访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆