Как найти файл jvm

How does one obtain the location of the executable of the currently running JVM during runtime? I would like to instantiate another JVM as a subprocess using the ProcessBuilder class.

I am aware that there is the java.home System property, but this doesn’t specify the location of the JVM executable. I understand I could do something like this to get the path:

System.getProperties().getProperty("java.home") + File.pathSeparator + "bin" + File.pathSeparator + "java"

This code isn’t platform independent, because the Windows executable’s name is java.exe, not java. Is there a way to get the path of the JVM executable that takes the platform’s idiosyncrasies into account?

asked Aug 2, 2010 at 22:53

Samad Lotia's user avatar

5

You could always just use os.name to check if the user is running Windows or not. That’ll work on OS X, Linux and Windows at

String jvm_location;
if (System.getProperty("os.name").startsWith("Win")) {
    jvm_location = System.getProperties().getProperty("java.home") + File.separator + "bin" + File.separator + "java.exe";
} else {
    jvm_location = System.getProperties().getProperty("java.home") + File.separator + "bin" + File.separator + "java";
}

cello's user avatar

cello

5,3063 gold badges22 silver badges28 bronze badges

answered Jun 18, 2014 at 21:07

Xenxier's user avatar

XenxierXenxier

4214 silver badges7 bronze badges

0

Following code obtains path to current java executable by using ProcessHandle.Info of current ProcessHandle.

Result is wrapped in Optional since the access to command info may be restricted by operating system permissions.

String javaExecutablePath = ProcessHandle.current()
    .info()
    .command()
    .orElseThrow();

answered May 18, 2020 at 1:13

czerny's user avatar

czernyczerny

14.7k14 gold badges68 silver badges94 bronze badges

3

This thread has an interesting discussion of the issue covering several platforms:
Finding current executable’s path without /proc/self/exe

Given that discussion, it should be possible, if you really needed it, to write some JNI wrapper that #ifdef’s the current platform and makes the proper native call.

If you’re only on Linux the ‘/proc/self/exe’ is a symbolic link to the actual executable being run. This has the advantage of not relying on any environment variables (i.e. PATH or JAVA_HOME). But as I said, it’s definitely not platform independent.

Community's user avatar

answered May 13, 2013 at 18:53

pedorro's user avatar

pedorropedorro

2,99924 silver badges24 bronze badges

Yes, there is a way to get the path of the JVM executable (if it exists). Include it in the configuration of the application. There are lots of ways to do that: Command line argument — java myApp.Main /path/to/Java; Properties — java -Dpath.to.java=/path/to/java; etc.

If you want true platform independence, then your whole scheme is flawed because the existence of a JVM executable is not guaranteed. I could imagine a JVM with no need for a java executable.

If you want 99.99% platform independence, then I think you have the tools needed.

answered Aug 3, 2010 at 2:36

emory's user avatar

emoryemory

10.7k2 gold badges30 silver badges58 bronze badges

2

You are trying to fork the entire JVM.

  1. That is extremely inefficient, mainly because of the heaviness of yet another java process. If your heavily doing this, then your program is going to be really slow
  2. Threads exist for this very reason

But if you really must, you can try just executing java -arguments directly, since most standard java installations put java on the cli path.

answered Aug 3, 2010 at 2:26

TheLQ's user avatar

TheLQTheLQ

14.8k14 gold badges69 silver badges107 bronze badges

3

На чтение 5 мин. Просмотров 292 Опубликовано 05.05.2021

Ошибка «В вашей системе не найдена JVM (Exe4j_Java_Home)» обычно появляется, когда пользователи пытаются установить DbVisualizer, при запуске исполняемого файла exe4j или при попытке запустить Minecraft ( или другую игру или приложение, использующее среду Java).

В большинстве случаев эта проблема будет возникают из-за несовместимой версии Java. Чаще всего затронутые пользователи устанавливают неправильную битовую версию Java, что заставляет приложение выдавать эту ошибку. Однако в некоторых случаях ошибка «В вашей системе не найдена JVM (Exe4j_Java_Home)» возникает из-за неправильной переменной среды Java.

Но если вы столкнулись с проблемой в отношении сервера Openfire, скорее всего, это связано с ошибкой, которая с тех пор была устранена в версиях Java более новых, чем Java 8. Обновление 161.

Примечание . Вот как исправить «Ошибка Javac не распознается».

Содержание

  1. 1. Установите совместимую версию DbVisualiser
  2. 2. Исправление переменной среды Java
  3. 3. Переустановите текущую среду Java

1. Установите совместимую версию DbVisualiser

Как сообщают многие затронутые пользователи, эта проблема, скорее всего, возникает из-за несовместимой установки Java. Наиболее затронутым пользователям удалось решить проблему после того, как они осознали, что они пытались развернуть 32-версию DbVisualiser с 64-разрядной установкой Java (или наоборот).

Если это сценарий применимо, вы можете быстро решить проблему, просто установив недостающую битовую версию установки Java. Вот краткое руководство, как это сделать:

Примечание. Приведенное ниже руководство должно применяться независимо от используемой вами версии Windows.

  1. Перейдите по этой ссылке ( здесь ) и прокрутите вниз до раздела Windows. Как только вы попадете туда, нажмите на недостающую битовую версию, чтобы начать загрузку. В зависимости от вашей разрядной версии DbVisualiser загрузите Windows Offline или Windows Offline (64-разрядная версия) .

    Примечание. Windows Offline – это 32-разрядная версия из трех доступных вариантов.

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

Если эта процедура не применима или не решила проблему, перейдите к следующему потенциальному исправлению ниже.

2. Исправление переменной среды Java

Как оказалось, ошибка «В вашей системе не найдена JVM (Exe4j_Java_Home)» также может возникать из-за неправильного Переменная среды Java. Это может произойти по разным причинам, но исправление всегда одно и то же.

Чтобы решить проблему, вам нужно будет получить местоположение вашей установки Java и убедиться, что Переменная Java Environment указывает правильное местоположение. Несколько затронутых пользователей подтвердили, что эта операция, наконец, позволила им решить проблему.

Вот краткое руководство по исправлению вашей переменной среды Java:

  1. Откройте проводник и перейдите к пути установки вашей среды Java. Если вы не установили его в произвольном месте, вы найдете его в следующих местах:
     C:  Program Files  Java  * Версия Java * - 64-разрядная версия C:  Program Files (x86)  Java   * Версия Java * - 32-разрядная версия 
  2. Как только вы окажетесь в правильном месте, щелкните правой кнопкой мыши панель навигации и выберите Копировать адрес . из недавно появившегося контекстного меню.
  3. Скопировав правильное местоположение Java в буфер обмена, нажмите Клавиша Windows + R , чтобы открыть диалоговое окно Выполнить . Затем введите « sysdm.cpl» в текстовое поле и нажмите Enter , чтобы открыть экран Свойства системы .
  4. Как только вы окажетесь в окне Свойства системы , перейдите на вкладку “Дополнительно”, затем нажмите Переменные среды .
  5. Находясь в окне Переменная среды , перейдите в Системные переменные , выберите параметр Путь и нажмите Редактировать .
  6. В следующем окне найдите среду переменная, в которой упоминается Java. Когда вам удастся найти его, измените его значение на правильное местоположение, которое вы ранее указали на шаге 2.
  7. Перезагрузите компьютер и посмотрите, будет ли проблема решена при следующем запуске системы.

Если проблема не устранена, перейдите к последнему потенциальному исправлению ниже.

3. Переустановите текущую среду Java

Если вы столкнулись с этой проблемой по отношению к серверу Openfire, весьма вероятно, что вы столкнулись с этой проблемой из-за ошибки, которая с тех пор была устранена в последних выпусках Java. . К счастью, Oracle удалось решить эту проблему с помощью сборок новее, чем Java 8 Update 161.

Если этот сценарий применим, вы можете решить проблему, удалив всю среду Java + вспомогательные компоненты и установив последнюю версию версия снова. Этот метод был подтвержден как успешный для многих затронутых пользователей, которые боролись с “В вашей системе не найдена JVM (Exe4j_Java_Home)”.

Вот краткое руководство с тем, что вам нужно сделать для переустановки текущей среды Java:

  1. Нажмите Клавиша Windows + R , чтобы открыть диалоговое окно Выполнить . Затем введите ‘appwiz.cpl’ и нажмите Enter , чтобы открыть экран Программы и компоненты .
  2. Находясь на экране Программы и компоненты , прокрутите вниз список установленных приложений и найдите свою версию установки Java. Когда вы его увидите, щелкните его правой кнопкой мыши и выберите Удалить в появившемся контекстном меню.
  3. После удаления основной установки Java повторите ту же процедуру с каждой вспомогательной установкой (обновления Java, NodeJs и т. д.).
    Примечание: Если вы хотите сгруппировать их все вместе, чтобы ничего не оставить, щелкните столбец Publisher вверху.
  4. После каждого Установка Java была удалена, перезагрузите компьютер.
  5. После завершения следующей последовательности запуска перейдите по этой ссылке здесь и загрузите последнюю версию JRE. После того, как вам удастся установить его, продолжите удаление остальных связанных компонентов, которые вы ранее удалили.
  6. Выполните последний перезапуск и посмотрите, будет ли проблема решена при следующем запуске системы.

Ошибка «Не удается найти JVM в вашей системе (Exe4j_Java_Home)», как правило, возникает, когда пользователи пытаются установить DbVisualizer, при запуске исполняемого файла exe4j или при попытке запустить Minecraft (или другую игру или приложение, использующее среду Java).

В вашей системе не найден Jvm (exe4j_java_home)

В большинстве случаев эта проблема возникает из-за несовместимой версии Java. Чаще всего уязвимые пользователи заканчивают тем, что устанавливали неправильную битовую версию Java, что вынуждает приложение выдавать эту ошибку. Однако в некоторых случаях из-за неверной переменной среды Java появляется ошибка «В вашей системе не может быть JVM» (Exe4j_Java_Home).

Но если вы столкнулись с проблемой, связанной с сервером Openfire, это, скорее всего, связано с ошибкой, которая была устранена с помощью выпусков Java, более новых, чем Java 8 Update 161.

Примечание. Ниже описано, как исправить ошибку «Javac not распознана».

1. Установите совместимую версию DbVisualiser.

Как сообщают многие затронутые пользователи, эта проблема, скорее всего, возникает из-за несовместимой установки Java. Большинству затронутых пользователей удалось решить проблему, поняв, что они пытаются развернуть 32-версию DbVisualiser с 64-разрядной установкой Java (или наоборот).

Если этот сценарий применим, вы можете быстро устранить проблему, просто установив недостающую битовую версию установки Java. Вот краткое руководство по этому:

Примечание. Приведенное ниже руководство должно применяться независимо от используемой версии Windows.

  1. Посетите эту ссылку (Вот) и прокрутите вниз до раздела Windows. Как только вы попадете туда, нажмите на битовую версию, которая вам не хватает, чтобы начать загрузку. В зависимости от версии бита DbVisualiser, загрузите Windows Offline или Windows Offline (64-разрядная версия).Загрузка правильной версии среды Java

    Примечание. Windows Offline — это 32-разрядная версия из трех доступных вариантов.

  2. После завершения загрузки дважды щелкните исполняемый файл установки, а затем следуйте инструкциям на экране для завершения установки.Установка правильной среды Java
  3. После завершения установки закройте мастер установки и перезагрузите компьютер.
  4. При следующем запуске повторите действие, которое ранее вызывало ошибку, и посмотрите, решена ли теперь проблема.

Если эта процедура неприменима или не решает проблему, перейдите к следующему потенциальному исправлению ниже.

2. Исправление переменной среды Java

Как выясняется, ошибка «В вашей системе не найдена JVM (Exe4j_Java_Home)» также может возникать из-за неверной переменной среды Java. Это может произойти по разным причинам, но исправление всегда одинаково.

Чтобы решить эту проблему, вам нужно выбрать местоположение вашей установки Java и убедиться, что переменная среды Java указывает на правильное местоположение. Несколько затронутых пользователей подтвердили, что эта операция, наконец, позволила им решить проблему.

Вот краткое руководство по исправлению вашей переменной среды Java:

  1. Откройте проводник и перейдите к пути установки вашей среды Java. Если вы не установили его в произвольном месте, вы найдете его в следующих местах: C: Program Files Java * Java version * — 64-разрядная версия
    C: Program Files (x86) Java * Java версия * — 32-разрядная версия
  2. Как только вы прибудете в правильное местоположение, щелкните правой кнопкой мыши на панели навигации и выберите «Копировать адрес» из появившегося контекстного меню.Копирование адреса Java из правильного местоположения
  3. Когда в буфере обмена скопировано правильное расположение Java, нажмите клавиши Windows + R, чтобы открыть диалоговое окно «Выполнить». Затем введите «sysdm.cpl» в текстовом поле и нажмите Enter, чтобы открыть экран «Свойства системы».Введите «sysdm.cpl» и нажмите «Enter»
  4. Когда вы окажетесь в окне «Свойства системы», перейдите на вкладку «Дополнительно» и нажмите «Переменные среды».Перейдите на вкладку «Дополнительно» в «Свойствах системы» и нажмите «Переменные среды».Перейдите на вкладку «Дополнительно» в «Свойствах системы» и нажмите «Переменные среды».
  5. Когда вы находитесь в окне переменных среды, перейдите к системным переменным, выберите опцию «Путь» и нажмите кнопку «Изменить».Изменить переменную PathИзменить переменную Path
  6. В следующем окне найдите переменную среды, в которой упоминается Java. Когда вам удастся найти его, измените его значение на правильное местоположение, которое вы ранее определили на шаге 2.
  7. Перезагрузите компьютер и посмотрите, будет ли проблема решена при следующем запуске системы.

В случае, если та же проблема все еще возникает, перейдите к финальному возможному исправлению ниже.

3. Переустановите текущую среду Java

Если вы столкнулись с этой проблемой в отношении сервера Openfire, очень вероятно, что вы столкнулись с этой проблемой из-за ошибки, которая с тех пор была решена в последних выпусках Java. К счастью, Oracle удалось решить эту проблему с помощью сборок, более новых, чем Java 8 Update 161.

Если этот сценарий применим, вы можете устранить проблему, удалив всю среду Java + вспомогательные средства и повторно установив последнюю версию. Этот метод был подтвержден как успешный для многих затронутых пользователей, которые боролись с «В вашей системе не удалось найти JVM (Exe4j_Java_Home)».

Вот краткое руководство о том, что вам нужно сделать, чтобы переустановить текущую среду Java:

  1. Нажмите клавишу Windows + R, чтобы открыть диалоговое окно «Выполнить». Затем введите «appwiz.cpl» и нажмите Enter, чтобы открыть экран «Программы и компоненты».Введите «appwiz.cpl» в строке «Выполнить»
  2. Как только вы окажетесь на экране «Программы и компоненты», прокрутите список установленных приложений и найдите версию установки Java. Когда вы увидите его, щелкните его правой кнопкой мыши и выберите «Удалить» из появившегося контекстного меню.Удаление каждой установки JavaУдаление каждой установки Java
  3. Как только основная установка Java будет удалена, повторите ту же процедуру для каждой вспомогательной установки (обновления Java, NodeJ и т. Д.).
    Примечание. Если вы хотите сгруппировать их все вместе, чтобы убедиться, что вы ничего не оставили, щелкните столбец «Издатель» вверху.
  4. После удаления всех установок Java перезагрузите компьютер.
  5. После завершения следующей последовательности запуска перейдите по этой ссылке Вот и загрузите последнюю версию JRE. После того, как вам удастся установить его, продолжайте удаление остальных связанных компонентов, которые вы ранее удалили.Загрузка правильной версии среды Java
  6. Сделайте окончательный перезапуск и посмотрите, будет ли проблема решена при следующем запуске системы.

Обновлено май 2023: перестаньте получать сообщения об ошибках и замедлите работу вашей системы с помощью нашего инструмента оптимизации. Получить сейчас в эту ссылку

  1. Скачайте и установите инструмент для ремонта здесь.
  2. Пусть он просканирует ваш компьютер.
  3. Затем инструмент почини свой компьютер.

Это очень распространенная ошибка, с которой пользователи Windows сталкиваются при попытке запустить приложения на основе Java, и Windows не может найти среду выполнения Java, необходимую для запуска приложений Java.

С этой ошибкой также сталкиваются тысячи пользователей Minecraft. Java требуется для запуска Minecraft и всех других игр на основе Java. Java позволяет разработчикам создавать кроссплатформенные приложения.

Эта ошибка возникает из-за несовместимость между Java (64-битной ИЛИ 32-битной) на вашем компьютере и программное обеспечение, которое вы пытаетесь установить. Чтобы исправить эту ошибку, вы можете установить на свой компьютер наборы инструментов JDK для x64 и x32.

Этот тип ошибки возникает, когда пользователь пытается установить DbVisualizer, обращаясь к исполняемому файлу exe4j. Установка совместимой версии DbVisualiser или добавление новой переменной среды, связывающей путь к Java SDK, решит проблему.

Как исправить ошибку «Не удалось найти JVM» в Windows 10?

Обновление за май 2023 года:

Теперь вы можете предотвратить проблемы с ПК с помощью этого инструмента, например, защитить вас от потери файлов и вредоносных программ. Кроме того, это отличный способ оптимизировать ваш компьютер для достижения максимальной производительности. Программа с легкостью исправляет типичные ошибки, которые могут возникнуть в системах Windows — нет необходимости часами искать и устранять неполадки, если у вас под рукой есть идеальное решение:

  • Шаг 1: Скачать PC Repair & Optimizer Tool (Windows 10, 8, 7, XP, Vista — Microsoft Gold Certified).
  • Шаг 2: Нажмите «Начать сканирование”, Чтобы найти проблемы реестра Windows, которые могут вызывать проблемы с ПК.
  • Шаг 3: Нажмите «Починить все», Чтобы исправить все проблемы.

скачать

Установите совместимую версию DbVisualiser

Как сообщают многие затронутые пользователи, эта проблема, скорее всего, связана с несовместимой установкой Java. Большинство затронутых пользователей смогли решить проблему, поняв, что они пытались использовать 32-разрядную версию DbVisualiser с 64-разрядной установкой Java (или наоборот).

  1. Перейти к этому ссылке и прокрутите вниз до раздела Windows.
  2. Там нажмите на недостающую битовую версию, чтобы начать загрузку.
  3. В зависимости от бинарной версии DbVisualiser загрузите Windows Offline или Windows Offline (64-разрядная версия).
  4. После завершения загрузки дважды щелкните исполняемый файл установки и следуйте инструкциям на экране, чтобы завершить установку.
  5. По завершении установки закройте мастер установки и перезагрузите компьютер.
  6. В следующий раз, когда вы запустите его, повторите действие, вызвавшее предыдущую ошибку, и посмотрите, устранена ли проблема.

Переустановка текущей среды Java

Если эта проблема возникает в контексте сервера Openfire, скорее всего, это связано с ошибкой, исправленной в последних версиях Java. К счастью, Oracle удалось решить эту проблему в новых версиях Java 8 Update 161.

  1. Нажмите клавиши Windows + R, чтобы открыть диалоговое окно «Выполнить».
  2. Затем введите «appwiz.cpl» и нажмите Enter, чтобы открыть окно «Программы и компоненты».
  3. На экране «Программы и компоненты» прокрутите список установленных приложений и найдите свою версию установки Java.
  4. Когда вы его увидите, щелкните его правой кнопкой мыши и выберите «Удалить» во всплывающем меню.
  5. После удаления основной установки Java повторите тот же процесс с каждой дополнительной установкой (обновления Java, NodeJs и т. Д.).
  6. После удаления каждой установки Java перезагружайте компьютер.
  7. После завершения следующей последовательности загрузки перейдите к этому ссылке и загрузите последнюю версию JRE.
  8. После завершения установки перейдите к удалению остальных связанных компонентов, которые вы ранее удалили.
  9. Выполните окончательную перезагрузку и проверьте, устранена ли проблема при следующем запуске системы.

Совет экспертов: Этот инструмент восстановления сканирует репозитории и заменяет поврежденные или отсутствующие файлы, если ни один из этих методов не сработал. Это хорошо работает в большинстве случаев, когда проблема связана с повреждением системы. Этот инструмент также оптимизирует вашу систему, чтобы максимизировать производительность. Его можно скачать по Щелчок Здесь

Часто задаваемые вопросы

Выберите путь, щелкнув правой кнопкой мыши Путь и выбрав Копировать адрес. Теперь откройте «Компьютер» -> «Свойства системы» -> «Дополнительные параметры системы» -> «Дополнительно» -> «Переменные среды». В разделе «Системные переменные» нажмите «Создать» и введите следующую информацию. Нажмите ОК и перезагрузите компьютер.

Откройте командную строку. Перейдите в Пуск -> Программы -> Стандартные -> Командная строка. Введите: java version и нажмите Enter на клавиатуре. Результат: сообщение, подобное приведенному ниже, указывает на то, что Java установлена ​​и вы готовы использовать MITSIS в среде выполнения Java.

  1. Установите совместимую версию DbVisualiser.
  2. Установите переменную среды Java.
  3. Переустановите текущую среду Java.
  1. Перейдите на сайт www.java.com.
  2. Щелкните Бесплатная загрузка Java.
  3. Нажмите Принять и начните бесплатную загрузку.
  4. Щелкните «Выполнить». Совет. При появлении запроса в окне «Контроль учетных записей пользователей» нажмите «Да».
  5. Нажмите «Установить» и следуйте инструкциям на экране, чтобы завершить установку.

Сообщение Просмотров: 911

Время на прочтение
15 мин

Количество просмотров 22K

Не так давно в мире Java случилось грандиозное событие. Во всех актуальных версиях OpenJDK стал доступен Java Flight Recorder (или просто JFR).

Что такое Java Flight Recorder?

JFR – это механизм легковесного профилирования Java-приложения. Он позволяет записывать и в последствии анализировать огромное количество метрик и событий, происходящих внутри JVM, что значительно облегчает анализ проблем. Более того, при определённых настройках его накладные расходы настолько малы, что многие (включая Oracle) рекомендуют держать его постоянно включённым везде, в том числе прод, чтобы в случае возникновения проблем сразу иметь полную картину происходившего с приложением. Просто мечта любого SRE!

Раньше этот механизм был доступен только в коммерческих версиях Java от корпорации Oracle версии 8 и более ранних. В какой-то момент его реимплементировали с нуля в OpenJDK 12, затем бекпортировали в OpenJDK 11, которая является LTS-версией. Однако вот OpenJDK 8 оставалась за бортом этого праздника жизни. Вплоть до выхода апдейта 8u272, в который наконец-то тоже бекпортировали JFR. Теперь все (за редким исключением) пользователи OpenJDK могут начинать использовать эту функциональность.

Но вот незадача: большая часть документации в интернете относится к старой, коммерческой, версии JFR и во многом не соответствует версии, которая присутствует в OpenJDK. Да и та, что есть, весьма скудная и не способствует пониманию того, как это всё использовать.

В предлагаемой вашему вниманию статье я расскажу, как управлять работой JFR и как его настраивать.

Активация через параметры JVM

Активировать JFR можно несколькими путями. Один из них – задать соответствующие параметры при запуске Java-приложения. Для этого необходимо использовать два параметра:

  • -XX:StartFlightRecording (активирует JFR и определяет основные параметры его работы),
  • -XX:FlightRecorderOptions (задаёт дополнительные параметры работы).

Каждая из этих опций может быть дополнена настройками, например:

java -XX:StartFlightRecording=filename=/path/to/record/file.jfr

или

java -XX:StartFlightRecording:filename=/path/to/record/file.jfr

задаёт путь к файлу, куда будет записана вся собранная JFR информация после завершения записи (или остановки приложения).

Опций может быть несколько. В таком случае они разделяются запятыми (без пробелов!).

Посмотрим, какие есть настройки у каждой из этих опций и для чего они нужны.

XX:StartFlightRecording

Посмотреть список опций можно в первоисточнике. В исходном файле OpenJDK. Для OpenJDK 11 это файл src/hotspot/share/jfr/dcmd/jfrDcmds.cpp.

XX:FlightRecorderOptions

Посмотреть список опций можно в исходном файле src/hotspot/share/jfr/recorder/service/jfrOptionSet.cpp.

Примеры использования

Минимально возможный пример запуска Java с JFR выглядит так:

java -XX:StartFlightRecording -version

В результате в консоль будет выдано сообщение:

Started recording 1. No limit specified, using maxsize=250MB as default.

Use jcmd 4787 JFR.dump name=1 filename=FILEPATH to copy recording data to file.
openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-b01)
OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)

Тут мы видим, что, помимо версии Java, запрашиваемой параметром -version, выведены ещё две строки:

  • сообщение о том, что JFR запущен и с каким идентификатором,
  • подсказка, как получить результаты работы JFR через утилиту jcmd.

В параметрах мы не указали никаких настроек. Т.о., в силу быстрого завершения выполнения (сразу после вывода версии Java) мы не сможем получить результаты в виде файла. Данные JFR будут накапливаться в памяти и пропадут при остановке приложения.

Чтобы это исправить, можно задать дополнительные опции:

java -XX:StartFlightRecording=filename=recording.jfr -version

В результате по окончании работы приложения записанные данные будут сброшены в файл recording.jfr в текущем каталоге.

Вместо имени файла, можно указать имя каталога:

java -XX:StartFlightRecording=filename=./ -version

Тогда имя конкретного файла будет сгенерировано в момент записи, например: hotspot-pid-16330-id-1-2020_11_30_17_16_49.jfr. Это может быть полезно, если запускается много экземпляров JVM и не хочется перетирать данные предыдущих запусков.

Как было отмечено ранее, по умолчанию JFR накапливает все снятые данные в памяти в течение всей работы приложения. Полностью память при этом под записанные данные использоваться не будет. JFR имеет ряд настроек, ограничивающих максимальное использование памяти. Но что делать, если хочется производить запись в течение длительного времени, не забивая при этом память?

В таком случае можно использовать набор настроек, позволяющих сбрасывать записанные данные по частям на диск:

java 
  -XX:StartFlightRecording=disk=true,maxsize=10g,maxage=24h,filename=./recording.jfr 
  -XX:FlightRecorderOptions=repository=./diagnostics/,maxchunksize=50m,stackdepth=1024 
  -jar application.jar

Прежде всего необходимо установить опцию disk=true, чтобы переключить JFR из режима записи в память в режим записи на диск.

Далее необходимо указать каталог, в который будет производиться запись: repository=./diagnostics/. В этом каталоге начнут появляться файлы с фрагментами записи данных JFR. Размер каждого такого отдельного фрагмента задаётся опцией maxchunksize=50m, но не стоит обманываться. Этот параметр задаёт размер чистых данных JFR, но в каждый файл в конце будет дописываться ещё довольно много служебной информации, что в отдельных случаях может увеличить размер файла в разы. Зато каждый такой файл будет самодостаточным и доступным для независимого изучения.

По умолчанию файлы будут писаться до бесконечности, пока приложение не остановится. Но, если оно будет работать достаточно долго, место на диске может закончиться. Чтобы этого не произошло, можно ограничить количество сохраняемых данных по времени (maxage=24h) или объёму (maxsize=10g). Если один из этих параметров будет превышен, то старые файлы в каталоге ./diagnostics/ начнут стираться.

Ну и последний параметр из приведённого ранее примера — stackdepth=1024. Он необходим для приложений с глубокими стеками вызовов, чтобы стек захватывался полностью.

Т.о., мы получаем конфигурацию, которую можно задавать для долго работающих приложений и при этом иметь возможность ретроспективно увидеть, что конкретно происходило с приложением на момент, когда ему «поплохело».

Единственный существенный момент, который остался за скобками, — настройка снимаемых метрик JFR.

Файл конфигурации профиля JFR

По умолчанию с OpenJDK поставляется два преднастроенных профиля:

  • default.jfc (предназначен для мониторинга приложений на проде и дающий пенальти около 1% производительности),
  • profile.jfc (предназначен для профилирования приложений на проде и дающий пенальти около 2% производительности и значительно больший объём снимаемых данных (больший размер jfr файлов).

Оба профиля тщательно подобраны разработчиками OpenJDK и лежат в каталоге JAVA_HOME/jre/lib/jfr для OpenJDK 8 или JAVA_HOME/lib/jfr для OpenJDK 11+.

Активировать их можно с помощью опции, например settings=profile.jfc:

java -XX:StartFlightRecording=settings=profile.jfc -version

Во многих ситуациях этого может оказаться достаточно, но не во всех. Дело в том, что в этих двух профилях остаётся отключённым очень большое количество метрик, которые могут очень помочь в тех или иных ситуациях. Например, в default.jfc практически отключён сбор информации о потреблении памяти, хотя он не даёт заметного пенальти, но при этом весьма полезен для понимания того, куда расходуется память приложения.

Т.о., становится понятно, что для своих частных случаев имеет смысл формировать отдельный, специально заточенный под себя файл с настройками. Но править его вручную – дело неблагодарное. Поэтому рекомендуется воспользоваться инструментом Java Mission Control (JMC), который умеет не только просматривать файлы, записанные JFR, но и управлять профилями записи этих файлов.

Скачать дистрибутив JMC можно, например, с сайта компании BellSoft.

Если мы запустим JMC и выберем пункт меню Window -> Flight Recording Template Manager, то попадём в окно управления настройками профилей записи JFR:

По умолчанию тут будут представлены два профиля, поставляемые с OpenJDK. Но мы можем создать свой профиль, если сначала продублируем имеющийся профиль с помощью кнопки Duplicate, а потом выберем копию и нажмём кнопку Edit:

В открывшемся окне можно задать название профиля, его описание и настройки в упрощённом виде.

Но если упрощённых настроек не хватает, можно перейти в подробный режим, нажав кнопку Advanced:

Перейдя в такой режим настроек, можно включить дополнительные метрики для записи. Например, можно включить метрики:

  • ObjectAllocationInNewTLAB
  • ObjectAllocationOutsideTLAB

Как показано на скриншоте выше. Значимого пенальти по скорости это не создаёт, зато позволяет оценить, где и чем мусорит приложение в памяти, что часто позволяет находить весьма нетривиальные проблемы.

Немного о метриках TLAB

Важно понимать, как работает сбор данных метрик, чтобы правильно оценивать показываемые ими данные. JFR не пишет информацию о создании каждого объекта. Вместо этого, делается более хитрый ход: JVM не выделяет память напрямую из кучи, а отрезает от последней равные фрагменты и распределяет их по каждому потоку в отдельности. Локальное выделение объектов из таких локальных блоков происходит гораздо быстрее и без лишних блокировок. Так вот, в момент, когда очередной такой блок заканчивается, JFR записывает, при создании объекта какого класса это произошло, а также может записать стек, чтобы понять, в каком месте программы это произошло. Т.о., получается, что нельзя увидеть абсолютно всю информацию о выделяемых объектах, но при достаточно длительной работе приложения можно получить адекватную картину происходящего просто по закону больших чисел.

Также важно понимать, что если были внесены и сохранены какие-либо изменения в этом окне, доступ к простому виду настроек будет потерян. Настройки всегда будут открываться только в подробном виде.

После создания своего профиля работы JFR его можно экспортировать в отдельный файл и использовать в настройках запуска, указав путь к этому файлу:

java -XX:StartFlightRecording=settings=/path/to/custom/profile.jfc -version

Управление JFR через командную строку (jcmd)

Но что делать, если приложение уже работает и надо запустить запись JFR? Или приостановить запись по какой-то причине? Или ещё что-то сделать?

Для этого можно воспользоваться штатной утилитой OpenJDK — jcmd. Например, запустить JFR можно следующей командой:

jcmd <pid> JFR.start duration=60s filename=myrecording.jfr settings=/path/to/custom/profile.jfc

Где <pid> — PID процесса JVM, в котором необходимо запустить JFR. В ответ будет выдана информация о том, что JFR запущено и куда именно будет записан файл с результатом:

19380:
Started recording 2. The result will be written to:

/media/data/java/OpenJDK/lmc7.1.1/myrecording.jfr

Данная команда запускает запись JFR на 60 секунд и указывает на то, чтобы записать результат в файл myrecording.jfr. Причём при таком указании файл будет записан по пути, локальному относительно не каталога запуска jcmd, а каталога, из которого была запущена JVM, в которой запускается JFR.

В целом видно, что при использовании jcmd доступны все те же самые опции, что и при запуске через параметры JVM, но некоторые опции имеют другие имена, поэтому далее они будут рассмотрены подробнее.

Также в ответе jcmd видна цифра 2. Это имя записи. Если мы в дальнейшем захотим как-то повзаимодействовать с этой записью, нам необходимо будет использовать данное имя. Например, вот так можно остановить запись:

jcmd <pid> JFR.stop name=2

Утилита jcmd может выполнять несколько команд, связанных с JFR. Рассмотрим их по порядку.

JFR.start

Запускает запись JFR с заданным именем, аналогично параметру запуска JVM -XX:StartFlightRecording. Если имя явно не задано, оно генерируется автоматически и выводится в консоль.

Можно использовать следующие опции:

JFR.configure

Настраивает запись JFR аналогично параметру -XX:FlightRecorderOptions. Данная команда должна выполняться перед JFR.start, чтобы изменения вступили в силу.

JFR.stop

Останавливает запись и сбрасывает записанные данные в файл, указанный при старте или непосредственно при вызове данной команды.

JFR.dump

Эта команда позволяет получить записанные данные, не останавливая саму запись. Ещё одной отличительной особенностью данной команды от JFR.stop является возможность сохранить не всю запись, а только интересующую её часть.

JFR.check

Выводит информацию об активных записях JFR. Данная команда полезна, чтобы понять, запущена ли уже запись JFR в JVM и требуется ли её запускать или можно смотреть информацию в уже запущенной. А также чтобы убедиться, что записываются интересуемые события (метрики) JFR.

Примеры использования

Разберём типовой сценарий использования jcmd для работы с JFR.

В качестве подопытного буду использовать запущенный Java Mission Control, который ранее использовался для формирования настроек записи.

Прежде всего посмотрим, не запущена ли уже запись JFR:

jcmd <pid> JFR.check

Получаю результат:

vektor@work$ jcmd 28534 JFR.check
28534:
Recording 1: name=JMC_Default maxsize=100,0MB (running)

Видно, что уже запущена запись с именем JMC_Default.

Допустим, мне необходимо посмотреть, как расходуется куча JVM. Как понять, снимается данная информация в запущенной записи или нет? Для этого можно посмотреть подробную информацию и найти в ней настройки для jdk.ObjectAllocationInNewTLAB и jdk.ObjectAllocationOutsideTLAB. Выполняем:

jcmd <pid> JFR.check name=JMC_Default verbose=true

И получаем результат (сокращено для наглядности):

vektor@work$ jcmd 28534 JFR.check name=JMC_Default verbose=true
28534:
Recording 1: name=JMC_Default maxsize=100,0MB (running)

 Flight Recording (jdk.ActiveRecording)
   [enabled=true]
 Recording Setting (jdk.ActiveSetting)
...
 Allocation in new TLAB (jdk.ObjectAllocationInNewTLAB)
   [enabled=false,stackTrace=true]
 Allocation outside TLAB (jdk.ObjectAllocationOutsideTLAB)
   [enabled=false,stackTrace=true]
...

Видно, что интересующие меня метрики отключены. Но не беда: можно запустить отдельную запись в том же процессе JVM с интересующими меня настройками:

jcmd <pid> JFR.start 
  name=memory_profile 
  duration=10m 
  filename=/path/to/recording.jfr 
  settings=/path/to/memory_profile.jfc

И получим вывод:

vektor@work$ jcmd 28534 JFR.start name=memory_profile duration=10m filename=/path/to/recording.jfr settings=/path/to/memory_profile.jfc
28534:
Started recording 4. The result will be written to:

/path/to/recording.jfr

Видно, что запись успешно запустилась.

Также можно посмотреть список всех записей:

jcmd <pid> JFR.check

И убедиться, что наша запись работает параллельно с ранее запущенной:

vektor@work$ jcmd 28534 JFR.check
28534:
Recording 1: name=JMC_Default maxsize=100,0MB (running)

Recording 4: name=memory_profile duration=10m (running)

Через 10 минут мы получим файл с результатами записи, который готов к открытию и изучению в Java Mission Control.

Но что делать, если есть необходимость включить запись на постоянной основе и иметь возможность анализировать результаты за сутки или более? В таком случае памяти на все записываемые данные может не хватить, а значит, нужно активировать их сброс на диск по мере записи. Для этого можно предварительно выполнить команду:

jcmd 28534 JFR.configure repositorypath=/path/to/disk/cahce maxchunksize=20m

Таким образом мы зададим каталог, куда будет скидываться записываемая информация. Плюс мы устанавливаем размер одного файла. Т.е. данные будут писаться фрагментами по 20 Мб, каждый из которых будет самодостаточным, и его можно будет просматривать в JMC независимо от всех остальных файлов.

В результате выполнения команды увидим следующий ответ:

vektor@work$ jcmd 28534 JFR.configure repositorypath=/path/to/disk/cahce maxchunksize=20m
28534:
Repository path: /path/to/disk/cahce/2020_12_03_16_58_40_28534

Max chunk size: 20,0 MB

Т.е. настройки установлены успешно. Теперь можно запускать непрерывную запись JFR:

jcmd 28534 JFR.start 
  name=continuouse_record 
  disk=true 
  maxage=24h 
  maxsize=10g 
  settings=/path/to/memory_profile.jfc

Самым главным моментом в данном примере является включение записи на диск, вместо хранения данных в памяти. Также ограничиваем максимальное время хранения данных одними сутками, а размер – 10 Гб. Как минимум для того, чтобы диск не переполнился.

После этого в каталоге /path/to/disk/cahce/2020_12_03_16_58_40_28534 начнут появляться файлы с записанными данными. А при превышении ограничений по времени или размеру старые файлы будут стираться.

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

jcmd 28534 JFR.dump 
  name=continuouse_record 
  begin=-10m 
  filename=/path/to/recording.jfr

В результате получим вывод:

vektor@work$ jcmd 28534 JFR.dump name=continuouse_record begin=-10m filename=/path/to/recording.jfr
28534:
Dumped recording "continuouse_record", 13,1 MB written to:

/path/to/recording.jfr

Таким образом мы сохранили в файл данные за последние 10 минут. При этом сама запись не остановилась, и, если с приложением произойдёт ещё что-то интересное, мы сможем вытащить информацию за этот промежуток времени и проанализировать, что же с приложением случилось, во всех деталях.

Заключение

В данной статье мы рассмотрели, как можно управлять записью Java Flight Recorder, и актуальный набор параметров для этого.

За скобками осталось ещё очень много интересного, т. к. управлять записью можно ещё и программно. А также добавлять свои типы событий и метрик, а потом анализировать всю собранную информацию в Java Mission Control.

Но это всё уже темы для других статей.

А тем, кого интересует, как использовать JFR для анализа и оптимизации приложения, я рекомендую серию статей от Алексея Рагозина:

  • JDK Flight Recorder – a gem hidden in OpenJDK
  • Hunting down code hotspots with JDK Flight Recorder
  • Hunting down memory issues with JDK Flight Recorder

Понравилась статья? Поделить с друзьями:
  • Как найти ее где живет слепая
  • Как исправить сразу все ошибки в excel
  • Как составить семейный бюджет для 3 класса
  • Как найти приложение вконтакте в плей маркете
  • Как правильно составить заявление в прокуратуру на работодателя за невыплату зарплаты образец