Статьи

Oracle Java Mission Control: полное руководство

«Нам нравится следить за блогом Михаила Воронцова и узнавать его точку зрения на проблемы, связанные с производительностью Java. Нас несколько раз спрашивали, чем анализ ошибок в Takipi в Java отличается от Java Mission Control и Java Flight Recorder. Таким образом, хотя различия между инструментами довольно велики (в основном, JMC — это в основном настольное приложение, в то время как Takipi был специально разработан для крупномасштабных производственных сред), мы посчитали, что это будет хорошей возможностью добавить исчерпывающий обзор JMC.

Помимо Java Mission Control, являющегося настольным приложением, основное отличие состоит в том, что с Takipi вы получаете постоянный анализ ошибок вплоть до значений переменных и фактического кода, который вызывал каждую ошибку. Поэтому, где JMC дает большую ценность в профилировании, но останавливается на уровне трассировки стека, Takipi углубляется в реальный код, чтобы помочь вам воспроизводить и устранять производственные ошибки.

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

— Алексей Житницкий, Такипи

Михаил — главный блогер на java-performance.info. Он делает свои Java-приложения на 5% быстрее и компактнее снова и снова на работе. Михаил любит проводить время в саду и играть с сыном в одном из пригородов Сиднея (Австралия).

Содержание

1. Введение
2. Java Mission Control
3. Лицензия JMC
4. Мониторинг процессов в реальном времени
— 4.1 Триггеры событий
— 4.2 Вкладка «Память»
— 4.3 Вкладка Темы
5. Использование Java Flight Recorder
— 5.1 Как бегать
— 5.2 Начальный экран
— 5.3 Вкладка «Память»
— 5.4 Вкладка «Выделения»
— — 5.4.1 По классу
— — 5.4.2 по теме
— — 5.4.3 Профиль распределения
— 5.5 Кодовая вкладка
— — 5.5.1 Горячие методы
— — 5.5.2 Вкладка «Исключения»
— — 5.5.3 Вкладка Темы
— — 5.5.4 Вкладка ввода / вывода
6. Экосистема Java Production Tooling

1. Введение

В этой статье описывается Java Mission Control — инструмент JDK GUI, доступный начиная с Java 7u40, вместе с Java Flight Recorder.

2. Java Mission Control

Oracle Java Mission Control — это инструмент, доступный в Oracle JDK начиная с Java 7u40. Этот инструмент происходит из JRockit JVM, где он был доступен в течение многих лет. JRockit и его версия JMC были хорошо описаны в Oracle JRockit: Полное руководство, написанное двумя старшими разработчиками JRockit (также посетите блог Маркуса Хирта — первое место, где вы должны искать любые новости JMC).

Oracle JMC можно использовать для двух основных целей:

  • Мониторинг состояния нескольких запущенных Oracle JVM
  • Анализ файла дампа Java Flight Recorder

3. Лицензия JMC

Текущая лицензия JMC (см. «Дополнительные условия лицензии» здесь ) позволяет вам свободно использовать JMC для разработки, но она требует приобретения коммерческой лицензии, если вы хотите использовать ее в производстве.

4. Мониторинг процессов в реальном времени

Вы можете присоединиться к JVM, щелкнув по нему правой кнопкой мыши на вкладке JVM Browser главного окна и выбрав пункт меню «Start JMX Console». Вы увидите следующий экран. Здесь нет ничего необычного, просто обратите внимание на кнопки «+», которые позволяют добавить дополнительные счетчики на этот экран.

main_monitoring

4.1 Триггеры событий

Триггеры позволяют запускать различные действия в ответ на превышение определенных счетчиков JMX и (необязательно) превышение порогового значения в течение определенного периода времени. Например, вы можете запустить запись JFR в случае достаточно высокой загрузки процессора, чтобы понять, какой компонент его вызывает (и вы не ограничены одной записью!).

Обратите внимание, что триггеры работают на любом счетчике JMX (вы видите кнопку «Добавить…»?) — вы можете установить больше триггеров, чем доступно в стандартном дистрибутиве, и экспортировать настройки на диск. Вы даже можете работать со своими счетчиками JMX своего приложения.

триггеры

Перейдите на вкладку «Действие» в окне «Сведения о правиле» — здесь вы можете указать, какое действие вы хотите выполнить в случае события.

спусковой механизм действия

Обратите внимание, что вам нужно запустить приложение как минимум в Java 7 update 40, если вы хотите правильно использовать JFR — я не смог записать какие-либо события из JRE до Java7u40 (возможно, это была ошибка или несовместимость между некоторыми версиями JRE…) ,

4.2 Вкладка «Память»

Следующая вкладка «Память» предоставит вам сводную информацию о куче вашего приложения и сборке мусора. Обратите внимание, что вы можете запустить полный сборщик мусора и запросить дамп кучи с этой страницы (выделено на снимке экрана). Но, по сути, эта страница — просто приятный интерфейс с функциональностью, доступной из других источников.

объем памяти

4.3 Вкладка Темы

Эта вкладка позволяет вам видеть список запущенных потоков в вашем приложении с их текущими дампами стека (обновляется раз в секунду). Это также позволяет увидеть:

  • Состояние потока — работает или заблокирован / ждет
  • Имя замка
  • Если поток заблокирован
  • Сколько раз поток был заблокирован
  • Использование процессора в потоке!
  • Объем памяти, выделенный данному потоку с момента его запуска

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

темы-вкладка

5. Использование Java Flight Recorder

Java Flight Recorder (мы будем называть его JFR в оставшейся части этой статьи) является функцией JMC. С точки зрения пользователя, вы запускаете JFR с фиксированным временем записи / максимальным размером файла записи / максимальной длиной записи (ваше приложение может закончить до этого) и ждете, пока запись не будет завершена. После этого вы анализируете это в JMC.

5.1 Как запустить JFR

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

1
-XX:+UnlockCommercialFeatures -XX:+FlightRecorder

Далее, если вы хотите получить что-нибудь полезное от JFR, вам нужно подключиться к Java 7u40 или новее. В документации утверждается, что вы можете подключиться к любой JVM из Java 7u4, но я не смог получить никакой полезной информации от этих JVM.
Третье, что нужно иметь в виду, это то, что по умолчанию JVM позволяет выполнять трассировку стека только в безопасных точках. В результате в некоторых ситуациях вы можете получить неверную информацию о трассировке стека.
Документация JFR говорит вам, чтобы вы установили еще 2 параметра, если вы хотите более точные трассировки стека (вы не сможете установить эти параметры на работающей JVM):

1
-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints

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

5.2 Начальный экран JFR

jfr_main

Начальный экран записи JFR содержит графики использования процессора и кучи за периоды записи. Рассматривайте это просто как обзор вашего процесса. Единственное, что вы должны заметить на этом (и на других экранах JFR), — это возможность выбрать временной диапазон для анализа на любом графике. Установите флажок «Синхронизировать выбор», чтобы сохранить одинаковый временной диапазон в каждом окне — он позволит вам просматривать события, происходящие только в этом диапазоне.

На этом экране есть еще одна интересная функция: вкладка «Информация о JVM» внизу содержит значения всех параметров JVM, установленных в профилированной JVM. Вы можете получить их с помощью опции -XX: + PrintFlagsFinal JVM, но получить их удаленно через пользовательский интерфейс удобнее:

JAVA_OPTS

5.3 Вкладка «Память устройства записи полета Java»

Вкладка памяти предоставляет вам информацию о:

  • Использование оперативной памяти и кучи Java (вы можете легко догадаться, произошла ли во время записи перестановка или чрезмерный сбор данных).
  • Сборки мусора — когда, почему, как долго и сколько места было убрано.
  • Распределение памяти — внутри / снаружи TLAB, по трассе класса / потока / стека.
  • Снимок кучи — количество / объем памяти, занимаемой именем класса

По сути, эта вкладка позволит вам проверить скорость выделения памяти в вашем приложении, степень давления, которое он оказывает на GC, и какие пути кода ответственны за неожиданно высокие скорости выделения. У JFR также есть своя особая особенность — она ​​позволяет отслеживать TLAB и выделение глобальной кучи отдельно (распределения TLAB намного быстрее, потому что они не требуют какой-либо синхронизации).

В целом ваше приложение будет работать быстрее, если:

  • Распределяет меньше объектов (по количеству и объему выделенной оперативной памяти)
  • У вас меньше старых (полных) сборщиков мусора, потому что они медленнее и требуют остановки мира (по крайней мере, на некоторое время)
  • Вы минимизировали размещение объектов не в TLAB

Давайте посмотрим, как вы можете контролировать эту информацию. Вкладка «Обзор» показывает общую информацию о потреблении / распределении памяти / сборке мусора.

JFR-память

Здесь вы можете увидеть, как далеко «Committed Heap» от «Reserved Heap». Он показывает, сколько у вас маржи в случае всплесков ввода. Синяя линия («Используемая куча») показывает, сколько данных просачивается / остается в старом поколении: если ваш шаблон пилы растет с каждым шагом — ваше старое поколение растет. Самая низкая точка каждого шага приблизительно показывает объем данных в старом поколении (некоторые из них могут подходить для сбора мусора). Шаблон на скриншоте говорит о том, что приложение выделяет только недолговечные объекты, которые собирает GC молодого поколения (это может быть некоторая обработка без сохранения состояния).

Вы также можете проверить поле «Скорость выделения для TLAB» — оно показывает, сколько памяти выделяется в секунду (есть еще один счетчик, называемый «Уровень выделения для объектов», но в целом он должен быть довольно низким). 126 Мбит / с (в примере) — это довольно средняя скорость пакетной обработки (сравните ее со скоростью чтения с жесткого диска), но довольно высокая для большинства интерактивных приложений. Вы можете использовать этот номер в качестве индикатора для общей оптимизации размещения объектов.

Три следующих вкладки: «Сборки мусора», «GC Times» и «Конфигурация GC» довольно очевидны и могут служить источником информации о причинах GC и самых длительных паузах, вызванных GC (которые влияют на задержку вашего приложения).

5.4 Вкладка «Распределение записей в Java»

Вкладка «Распределения» предоставляет вам информацию обо всех распределениях объектов. Перейдите на вкладку «Распределение в новой TLAB». Здесь вы можете видеть профили распределения объектов по классам (какие экземпляры классов распределяются), по потокам (какие потоки распределяют большинство объектов) или по стеку вызовов (обрабатывать его как глобальную информацию о распределении).

JFR-распределение

5.4.1 Распределение по классам

Давайте посмотрим, что вы можете узнать из каждой из этих вкладок. Первый (на скриншоте выше), «Распределение по классам», позволяет увидеть, какие классы распределены больше всего. Выберите тип в средней вкладке, и вы получите статистику распределения (со следами стека) для всех распределений экземпляров этого класса.

Первая проверка, которую вы должны сделать здесь, — это найти любые «бесполезные» выделения объектов: любые примитивные оболочки, такие как Integer или Double (которые часто указывают на использование коллекций JDK), java.util.Date , java.util.GregorianCalendar , Pattern , любые средства форматирования и т. д. Я написал несколько советов по настройке памяти во второй части моей недавней статьи . Вкладка «Stack Trace» позволит вам найти код для улучшения.

Другой проблемой для проверки является чрезмерное распределение объектов. К сожалению, здесь нельзя дать общих советов — вы должны использовать свой здравый смысл, чтобы понять, что означает «чрезмерное» в вашем приложении. Распространенными проблемами являются бесполезное защитное копирование (для клиентов только для чтения) и чрезмерное использование String.substring, так как класс String изменяется в Java 7u6 .

5.4.2 Распределение по потокам

Вкладка «Распределение по потокам» может быть интересна, если у вас есть несколько типов обработки данных потоков в вашем приложении (или вы можете различить, какие задачи выполняются какими потоками) — В этом случае вы можете определить распределение объектов по потокам:

JFR-bythread

5.4.3 Профиль распределения

Если все ваши потоки одинаковы (или у вас есть только один поток обработки данных) или вы просто хотите просмотреть информацию о распределении высокого уровня, перейдите непосредственно на вкладку «Профиль распределения». Здесь вы увидите, сколько памяти было выделено для каждого стека вызовов во всех потоках.

JFR-распределение-профиль

Это представление позволяет вам найти пути кода, оказывающие наибольшее давление на подсистему памяти. Здесь следует различать ожидаемые и чрезмерные ассигнования. Например, если из метода A вы вызываете метод B более одного раза, а метод B выделяет некоторую память внутри него, и все вызовы метода B гарантированно возвращают один и тот же результат — это означает, что вы чрезмерно вызываете метод B. Другой пример чрезмерных вызовов метода Выделение / object может быть конкатенацией строк в вызовах Logger.log . Наконец, остерегайтесь любых оптимизаций, которые вынуждают вас создавать пул многократно используемых объектов — вы должны объединять / кэшировать объекты, только если у вас есть не более одного сохраненного объекта на поток (хорошо известный пример — ThreadLocal <DateFormat> ).

5.5 Вкладка «Код полета» в Java

Следующая большая вкладка в представлении JFR — вкладка «Код». Это полезно для оптимизации процессора:

JFR-код

Вкладка обзора предоставляет вам 2 вида: «Горячие пакеты», где вы можете увидеть время, потраченное на пакет Java, и «Горячие классы», которые позволяют вам увидеть самые дорогие классы ЦП в вашем приложении.

Представление «Горячие пакеты» может быть полезно, если вы используете сторонние библиотеки, над которыми у вас очень мало контроля, и вы хотите получить сводную информацию об использовании ЦП для своего кода (один пакет), стороннего кода (несколько других пакетов) и JDK (a еще несколько пакетов). В то же время я бы назвал это «представлением CIO / CTO», потому что оно не интерактивное и не позволяет увидеть, какие классы из этих пакетов виноваты. Как разработчик, вам лучше использовать фильтрацию для большинства других таблиц на этой вкладке:

хот-классы

5.5.1 Горячие методы / вкладки дерева вызовов

Вкладки «Горячие методы» и «Дерево вызовов» — это обычные представления, предоставляемые буквально любым профилировщиком Java. Они показывают горячие точки вашего приложения — методы, в которых ваше приложение проводило большую часть времени, а также пути кода, которые ведут к этим горячим точкам. Как правило, настройку ЦП приложения следует начинать с вкладки «Горячие методы», а затем проверять, достаточно ли нормальна общая картина на вкладке «Дерево вызовов».

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

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

JFR-hotmethods

5.5.2 Вкладка «Исключения»

Вкладка «Исключения» является последней вкладкой в ​​представлении «Код», на которую стоит обратить внимание в общем случае оптимизации. Бросать исключения Java очень медленно, и их использование должно быть строго ограничено исключительными сценариями в высокопроизводительном коде.

Представление «Исключения» предоставит вам статистику о количестве исключений, которые были сгенерированы во время записи, а также их следы стека и детали. Перейдите на вкладку «Обзор» и проверьте, видите ли вы:

  • Любые неожиданные исключения
  • Неожиданное количество ожидаемых исключений

Если вы видите что-то подозрительное, перейдите на вкладку «Исключения» и проверьте сведения об исключении. Постарайтесь избавиться хотя бы от самых многочисленных.

JFR-исключение

5.6 Вкладка Темы JFR

Вкладка Темы JFR предоставляет вам следующую информацию:

  • Использование ЦП / Диаграммы подсчета потоков
  • Профиль ЦП для каждого потока — аналогичен профилю на вкладке Код, но для каждого потока
  • Конфликт — какие потоки были заблокированы, какими и как долго
  • Задержки — что заставило потоки приложения перейти в состояние ожидания (здесь вы четко увидите некоторые издержки JFR)
  • Экземпляры блокировок — блокировки, вызвавшие конфликт потоков

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

5.7 Вкладка ввода / вывода JFR

Вкладка ввода / вывода должна использоваться для проверки ввода / вывода файлов и сокетов в вашем приложении. Он позволяет увидеть, какие файлы обрабатывает ваше приложение, каковы размеры чтения / записи и сколько времени потребовалось для завершения операции ввода-вывода. Вы также можете увидеть порядок событий ввода-вывода в вашем приложении.

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

  • Я вижу какие-либо неожиданные операции ввода-вывода (для файлов, которые я не ожидаю увидеть здесь)?
  • Открывать / читать / закрывать один и тот же файл несколько раз?
  • Ожидаются ли размеры блоков чтения / записи? Разве они не слишком маленькие?

Обратите внимание, что настоятельно рекомендуется уменьшить параметр JFR «File Read Threshold» (вы можете установить его при запуске записи JFR) до 1 мс, если вы используете SSD. Вы можете пропустить слишком много событий ввода-вывода на SSD с порогом по умолчанию 10 мс. Вкладка «Обзор» ввода / вывода отличная, но она не предоставляет никакой дополнительной информации по сравнению со следующими 4 специализированными вкладками. Каждая из 4 специализированных вкладок (чтение / запись файла, чтение / запись сокета) похожа друг на друга, поэтому давайте рассмотрим только одну из них — «Чтение файла».

JFR-ю

Здесь есть 3 вкладки: «По файлу», «По теме» и «По событию». Первые две вкладки группируют операции по файлам и по потокам. Последняя вкладка просто перечисляет все события ввода / вывода, но это может быть очень полезно, если вы исследуете, какие операции были выполнены над конкретным файлом (фильтр по «Путь») или если вы хотите выяснить, делали ли вы запросы на чтение для краткости фрагменты данных (отсортированные по «Bytes Read»), которые снижают производительность приложения. Как правило, вы всегда должны буферизовать чтение диска, чтобы только чтение файла было короче размера буфера.

Обратите внимание, что информация ввода / вывода также собирается с помощью выборки, поэтому некоторые (или многие) файловые операции будут отсутствовать на вкладке ввода / вывода. Это может быть особенно заметно на SSD-накопителях высшего класса.

Есть еще один связанный экран, который позволит вам группировать события ввода / вывода (и некоторые другие) по различным полям. Например, вы можете узнать, какое количество операций чтения прочитало данное число байтов (и проверить их трассировки стека). Перейдите на вкладку «События» слева от представления JFR, а затем на самую последнюю вкладку под названием «Гистограмма».

Здесь вы можете фильтровать / сортировать / группировать различные события по доступным столбцам. Каждое событие JFR имеет связанную трассировку стека, поэтому вы можете просмотреть информацию трассировки стека для выбранных событий:

JFR-IO-события

Существует одна базовая область настройки производительности, не охватываемая JFR: антипаттерны использования памяти, такие как дублирующиеся строки или почти пустые коллекции с огромной емкостью. JFR не предоставляет вам такой информации, потому что вам нужен дамп кучи для такого анализа. Вот где вам нужен плагин JMC под названием «Анализ JOverflow».

6. Экосистема Java Production Tooling

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

Ссылка: Oracle Java Mission Control: полное руководство от нашего партнера по JCG Михаила Воронцова в блоге Takipi .