openjdk.ruOpenJDK на русском

JEP 328: Flight Recorder

Регистратор событий Flight Recorder

AuthorsMarkus Grönlund, Erik Gahlin
ОтветственныйErik Gahlin
ТипFeature
ОбластьJDK
СтатусClosed / Delivered
Выпуск11
Компонентhotspot / jfr
Обсуждениеhotspot dash dev at openjdk dot java dot net
ТрудоёмкостьL
ДлительностьM
РецензентыDavid Holmes, Karen Kinnear, Mikael Vidstedt
ОдобренMikael Vidstedt
Создан2017/12/12 19:13
Обновлён2018/09/09 16:43
Задача8193393

Аннотация

Предоставить фреймворк для сбора данных с низкими накладными расходами, предназначенный для диагностики проблем Java-приложений и HotSpot JVM.

Цели

  • Предоставить API для создания и потребления данных в виде событий
  • Предоставить механизм буферизации и двоичный формат данных
  • Дать возможность настраивать и фильтровать события
  • Предоставить события для ОС, HotSpot JVM и библиотек JDK

Что не является целью

  • Предоставить визуализацию или анализ собранных данных
  • Включить сбор данных по умолчанию

Критерии успеха

  • Накладные расходы на производительность в конфигурации по умолчанию на SPECjbb2015 не более 1%
  • Отсутствие измеримых накладных расходов на производительность, когда запись не включена

Мотивация

Диагностика проблем, мониторинг и профилирование — неотъемлемые части жизненного цикла разработки, но некоторые проблемы возникают только в рабочей среде, под высокой нагрузкой и на реальных данных.

Flight Recorder записывает события, которые порождают приложения, JVM и ОС. События сохраняются в одном файле, который можно приложить к отчёту об ошибке и передать на изучение инженерам поддержки. Так можно постфактум проанализировать, что происходило в период, предшествовавший проблеме. Инструменты могут извлекать информацию из файлов записи с помощью API.

Описание

JEP 167: Event-Based JVM Tracing добавил в HotSpot JVM начальный набор событий. Flight Recorder распространит возможность создавать события на Java.

JEP 167 также добавил простейший бэкенд, который выводит данные событий в stdout. Flight Recorder предоставит единый высокопроизводительный бэкенд для записи событий в двоичном формате.

Модули:

  • jdk.jfr
    • API и внутренняя реализация
    • Требует только java.base (подходит для устройств с ограниченными ресурсами)
  • jdk.management.jfr
    • Возможности JMX
    • Требует jdk.jfr и jdk.management

Flight Recorder можно запустить из командной строки:

$ java -XX:StartFlightRecording ...

Запись также можно запускать и управлять ею с помощью инструмента bin/jcmd:

$ jcmd <pid> JFR.start
$ jcmd <pid> JFR.dump filename=recording.jfr
$ jcmd <pid> JFR.stop

Эта функциональность доступна удалённо через JMX, что полезно для таких инструментов, как Mission Control.

Создание и потребление событий

Пользователи могут создавать собственные события с помощью API:

import jdk.jfr.*;

@Label("Hello World")
@Description("Helps the programmer getting started")
class HelloWorld extends Event {
   @Label("Message")
   String message;
}

public static void main(String... args) throws IOException {
    HelloWorld event = new HelloWorld();
    event.message = "hello, world!";
    event.commit();
}

Данные можно извлекать из файлов записи с помощью классов из jdk.jfr.consumer:

import java.nio.file.*;
import jdk.jfr.consumer.*;

Path p = Paths.get("recording.jfr");
for (RecordedEvent e : RecordingFile.readAllEvents(p)) {
   System.out.println(e.getStartTime() + " : " + e.getValue("message"));
}

Механизм буферизации и двоичный формат данных

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

Модель событий реализована в самоописывающем двоичном формате в кодировке little endian base 128 (кроме заголовка файла и некоторых дополнительных разделов). Двоичный формат данных не предназначен для непосредственного использования, так как он может измениться. Вместо этого будут предоставлены API для работы с файлами записи.

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

<memory address>: 98 80 80 00 87 02 95 ae e4 b2 92 03 a2 f7 ae 9a 94 02 02 01 8d 11 00 00
  • Размер события [98 80 80 00]
  • ID события [87 02]
  • Временная метка [95 ae e4 b2 92 03]
  • Длительность [a2 f7 ae 9a 94 02]
  • ID потока [02]
  • ID трассировки стека [01]
  • Полезная нагрузка [поля]
    • Загруженный класс: [0x8d11]
    • Определяющий ClassLoader: [0]
    • Инициирующий ClassLoader: [0]

Настройка и фильтрация событий

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

  • enabled — записывать ли событие
  • threshold — длительность, ниже которой событие не записывается
  • stackTrace — записывать ли трассировку стека из метода Event.commit()
  • period — интервал, с которым порождается событие, если оно периодическое

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

События ОС, JVM и библиотек JDK

Будут добавлены события, охватывающие следующие области:

  • ОС
    • Память, загрузка процессора и сведения о процессоре, нативные библиотеки, сведения о процессе
  • JVM
    • Флаги, конфигурация сборщика мусора, конфигурация компилятора
    • Событие профилирования методов
    • Событие утечки памяти
  • Библиотеки JDK
    • Ввод-вывод через сокеты, файловый ввод-вывод, исключения и ошибки, модули

Альтернативы

Альтернатива Flight Recorder — журналирование. Хотя JEP 158: Unified JVM Logging обеспечивает определённое единообразие между подсистемами HotSpot JVM, на Java-приложения и библиотеки JDK оно не распространяется. Традиционно у журналирования обычно нет явной модели и метаданных, поэтому его формат свободный, и в результате потребители вынуждены жёстко зависеть от внутренних форматов. Без реляционной модели трудно хранить данные компактно и в нормализованном виде.

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

Тестирование

Потребуется тестирование производительности, чтобы убедиться, что накладные расходы находятся на приемлемом уровне.

Риски и допущения

Возможно, на основе JEP 167 были разработаны бэкенды, специфичные для отдельных поставщиков; рабочее допущение состоит в том, что инфраструктура Flight Recorder должна покрыть большинство существующих сценариев использования. Мы призываем поставщиков принять участие в обсуждении в рамках этого JEP того, насколько осуществим предлагаемый переход на единый бэкенд.

Flight Recorder существует уже много лет и ранее был коммерческой возможностью Oracle JDK. Этот JEP переносит исходный код в открытый репозиторий, чтобы сделать эту возможность общедоступной. Поэтому риск для совместимости, производительности, а также риск регрессий и нарушения стабильности невелик.