Инструменты для мониторинга Java VM и копания внутри

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

Программы

VisualVM

раньше в составе JDK были две утилиты: jconsole и visualvm, теперь jconsole удалена, а с Java 9 visualvm поставляется отдельно. Незаменимый помощник для профилирования кода. Бесплатен. Куча плагинов для профилирования кода и сбора статистики.

Java Mission Control

Раньше эта утилита шла в составе JDK. Теперь она выделена в отдельный проект. Старая jmc не понимает дампов новых JVM. Поэтому, если перешли на java12+ надо выкачивать JMC 7 (или уже JMC 8). Алексей Шипилёв на своем сайте в тёмной каморке выкладывает свежие билды JMC под MacOS X, Windows и Linux. Спасибо! Про JMC есть подробная презентация от Алексея Рагозина.

Update 2021.04.16: JMС ver.8 вышел. Правда с какими-то совершенно нелепыми багами.

jmh

микробенчмаркинг от Алексея Шипилёва (см. презентацию). Была раньше отдельная библиотека, теперь идет в составе JDK.

jmx

Java-интерфейс, через который можно собирать статистику с работающего приложения и управлять его свойствами.

[ См. также: Полезные Linux-команды — несколько утилит OS Lnux для оценки производительности системы ]

Утилиты JDK

javap декомпилятор в байткод. Все знают javac — компилятор, превращающий ваш исходник в байт-код. javap проделывает обратную операцию. Он декомпилирует байт-код в мнемо-код, который можно прочитать и понять, в какие именно байт-инструкции транслируются те или иные порции вашего исходного кода.

Для мониторинга приложения и сбора статистики можно использовать утилиты jps, jinfo, jstack и jmap.

# jps -mlv

Выведет список только Java-процессов на данной машине (в отличие от стандартного Unix/Linux ps). Выведет id процесса, его Main-class и параметры, с которыми процесс был запущен. Main-class и параметры полезны, чтобы отличить один процесс от другого, если у вас запущено несколько вариантов одной и той же программы с разными параметрами.

# jmap -heap <pid>

Выведет дамп памяти вашей Java-программы. Увы, работает только с Java 8, если утилита jmap из Java 8 JDK. Утилита считается экспериментальной и в новых JDK не поддерживается.

# jinfo <pid>

Выведет много-много полезной информации о параметрах JVM, флагах, аргументах запуска программы.

# jstack <pid>

Выведет дамп всех потоков вашей Java-программы. В дампе можно разглядеть, какой поток чем занимался в момент дампа: какой работал (и в каком месте кода он находился), какой — заблокирован, какой находится в ожидании и так далее. Эта информация полезна, если надо определить, где именно находится deadlock, или в каком месте конкретный «жадный» поток отъедает массу ресурсов.

[ См. также: Утилиты pidstat и jstack — заглядываем за кулисы Java-приложения ]

Стоит помянуть ещё одну полезную утилиту: jcmd. В новейших релизах JDK она заменяет старые утилиты, которые считаются устаревшими (deprecated) и экспериментальными (experimental) и больше не поддерживаются. Предполагается, что вместо зоопарка утилит jps, jinfo, jstack и jmap, достаточно освоить jcmd, которая эффективно заменит их все.

[ См. такжеКак jcmd помогает настроить JVM для low-latency ]

С помощью jcmd можно запускать и останавливать внутренний монитор сбора статистики Java Flight Recorder. Статистику можно записывать в файл, который можно просмотреть другой утилитой — Java Mission Control (о ней было уже сказано выше).

Обратите внимание, что в команде надо указывать pid процесса. Все дело в том, что у вас на машине может работать несколько Java-приложений под разными JVM. Например, у меня одно приложение до сих пор работает под Java 8, а другое — уже под Java 13. И для каждой JVM имеется свой набор команд, который поддерживает jcmd. Поэтому на некоторые команды Java8 может сказать «Not supported».

Сбор статистики как рутина

Важное замечание: При обращении данных утилит к JVM для сбора статистики, JVM должна на короткое время сбора данных остановиться сама и остановить все работающие потоки вашего приложения. Это значит не следует собирать статистику на PROD-е в критические для вашей системы моменты. Как правило я планирую сбор статистики с помощью  утилиты cron на определенные часы, когда рынок закрыт, торги не ведутся и останов JVM на короткое время ничему не критическому не помешает.

Автоматизация сбора статистики позволяет собирать данные за несколько дней и даже месяцев и точно следить за поведением и состоянием системы изо дня в день. Еще позволяет вам заметить изменения на PROD или QA серверах, которые были сделаны без вашего ведома технической командой (такое тоже бывает): патчи операционной системы, апгрейд версии Java, новые параметры командной строки. Например, неожиданно большие размеры данных в heap позволяют предположить, что в данный день в поведении вашего приложения были какие-то не рядовые события: через систему прошло необычно много запросов, где-то в системе произошел затык и она не успевала обрабатывать все данные, словом, что-то не обычное.

Java Agents

JVM имеет Java Agents API, который позволяет подключать к JVM сторонние утилиты. Java agents  — это «агенты», написанные на Java. Подключаются к приложению при старте с помощью параметра:

 -javaagent:<path-to-agent-jar>=<options>

JVM TI-агенты — другой способ подключить стороннюю утилиту к JVM при старте. JVMTI-агенты пишутся на C или C++. Они позволяют глубже заглянуть во внутренности JVM, но при этом высок риск грохнуть ее. Подключаются к приложению при старте с помощью параметра:

-agentlib:<agent-lib-name>=<options>

или

-agentpath:<path-to-agent>=<options>

Сторонние утилиты

Профилировщики — специальные утилиты, нацеленные на исследование качества исполнения вашего кода в JVM. Самым популярным является пожалуй YourKit. Но большинство профилировщиков — платные и требуют лицензии для коммерческого использования.

JITWatch — отличная open-source утилита, показывающая стадии компиляции вашего кода JIT-компилятором во время исполнения.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s