Заменить доступ к sun.misc.VM для JDK 11 - PullRequest
0 голосов
/ 29 ноября 2018

В OpenJDK 8 был возможен доступ к sun.misc.VM и вызов isDirectMemoryPageAligned и maxDirectMemory.
isDirectMemoryPageAligned используется для правильного размера прямой памяти для выделения, как это было сделано DirectByteBuffer .
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_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. : (

1 Ответ

0 голосов
/ 10 декабря 2018

Этот ответ приходит из различных комментариев Алан Бейтман к вопросу.

Нет, стандартного API для доступа к двум разыскиваемым методам нет.

Начиная с JDK 6, DirectxxxBuffers больше не выровнены по страницам.Таким образом, доступ к VM.isDirectMemoryPageAligned не требуется для воспроизведения того, что делают DirectBuffers.


О распределении памяти вручную, являющемся прецедентом для вопроса, единственный API для прямого распределения памяти в настоящее время ByteBuffer.allocateDirect или его альтернатива JNI NewDirectByteBuffer.


Ссылки на комментарии: 1 2 3

...