Параметр 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 (и частично написан на нем). Что делает более подробно:
создать новую JVM; это не использует исполняемый файл, поэтому его нелегко увидеть, но на самом деле это JVM, как и один из
используйте эту JVM для запуска предопределенного кода Java, который раньше находился в JDK/lib/tools.jar; Я не удосужился отследить, где он находится (и как именно получить к нему доступ) в новом модулированном Java после 8.
этот 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
-введите информацию о
jps
JVM.
Достаточно ясно?