Параметр Java MaxDirectMemorySize сообщается по-разному для java и jinfo

Я перезапустил процесс Java с новыми параметрами памяти -Xms4G -Xmx4G -XX:MaxDirectMemorySize=6Gи хотел проверить, правильно ли были применены эти изменения, особенно 6 ГБ прямой памяти.

Первое решение, которое я нашел для проверки этого, было через себя, но это просто сообщило о 0, подразумевая, что мои новые настройки не повлияли:

      bash-4.4$ java -XX:+PrintFlagsFinal -version | grep MaxDirect
    uintx MaxDirectMemorySize                = 0                          {product}
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)

Второе решение, которое я нашел позже, было через , что, по-видимому, подтверждает 6G что я намеревался установить:

      bash-4.4$ jinfo -flag MaxDirectMemorySize 1
-XX:MaxDirectMemorySize=6442450944

я полагался на java -XX:+PrintFlagsFinalдля других целей раньше, но теперь мне интересно, почему он не возвращает ожидаемые значения. Почему java и jinfo возвращая разные результаты?

1 ответ

Есть (по крайней мере) две разные JVM.

[Расширяющийся комментарий:] java {nothing} -XX:+PrintFlagsFinal -versionсоздает новую JVM, ничего не меняет в своей конфигурации по умолчанию и распечатывает результирующую конфигурацию, которая является конфигурацией по умолчанию без каких-либо изменений, а значение по умолчанию для MaxDirectMemSize действительно равно нулю.

ОТОН jinfo {option} pidприсоединяется к существующей уже запущенной JVM и получает или изменяет конфигурацию этой JVM (хотя конкретный pid 1 обычно не является JVM, но часто находится в контейнере докера, который вы используете). перечисляет запущенные JVM, к которым вы можете подключиться, с опциями для включения аргументов JVM и/или аргументов приложения.

Означает ли это, что такая же проверка не может быть достигнута с помощью ? В отличие от него нельзя подключиться к работающей JVM?

Да и нет; это становится немного Страной Чудес.

сам по себе создает новую JVM, отдельную от любой существующей. Обычно эта JVM запускает указанную пользователем программу, но с -versionкак вы использовали, он просто печатает информацию о версии и завершает работу, ничего не запуская.

Теперь API подключения доступен из Java (и частично написан на нем). Что делает более подробно:

  1. создать новую JVM; это не использует исполняемый файл, поэтому его нелегко увидеть, но на самом деле это JVM, как и один из

  2. используйте эту JVM для запуска предопределенного кода Java, который раньше находился в JDK/lib/tools.jar; Я не удосужился отследить, где он находится (и как именно получить к нему доступ) в новом модулированном Java после 8.

  3. этот Java-код при запуске в JVM присоединяется и получает доступ к информации в указанной другой JVM, которая была ранее создана и настроена с помощью java -Xvariousдля запуска вашего приложения

Вы можете сделать шаги 2 и 3 самостоятельно; вы можете написать код Java, который использует API для подключения к указанной (или иным образом расположенной) существующей JVM и получить нужную информацию, а также использовать javaдля запуска в JVM#2 вашего кода, который обращается к информации в существующей JVM#1. Но зачем беспокоиться, когда (и jstat jmap jconsoleи т.д.) уже делает то, что нужно?

Если на то пошло, также делает это - он запускает свою собственную JVM для запуска кода "инструмента" Java, который использует API прикрепления для перечисления JVM. Вот почему список, созданный , если не отфильтрован, включает себя. На самом деле, если бы вы могли работать в течение очень короткого времени работы, список также включал бы -- и если бы вы могли определить pid для и запускать этот pid в течение очень короткого времени работы, вы могли бы получить jinfo-введите информацию о jpsJVM.

Достаточно ясно?

Другие вопросы по тегам