Flame-графики: «огонь» из всех движков

Автор оригинала: Michael Hunger
  • Перевод

Всем снова привет! Приглашаем на онлайн-встречу с Василием Кудрявцевым (директором департамента обеспечения качества в АО «РТЛабс»), которая пройдёт в рамках курса «Нагрузочное тестирование». И публикуем перевод статьи Michael Hunger — software developer and editor of Neo4j Developer Blog and GRANDstack!

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

К счастью, Брендан Грегг, инженер по производительности в Netflix, придумал flame-графики, гениального вида диаграммы для трассировки стека, которые можно собрать практически из любой системы.

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

Flame-график бенчмарка заполнения непредаллоцированного ArrayList
Flame-график бенчмарка заполнения непредаллоцированного ArrayList

Flame'ы снизу вверх отражают прогрессию от точки входа программы или потока (main или цикл событий) до листьев выполнения на концах flame'ов.

Вы сразу увидите, если некоторые части программы будут занимать неожиданно большое количество времени. Чем выше на диаграмме вы это видите, тем хуже. А если у вас есть очень широкий flame сверху, то вы точно нашли узкое место, где работа не делегируется куда-либо еще. После устранения проблемы, измерьте время работы еще раз, если проблема с производительностью сохранится, вернитесь к диаграмме, чтобы понять, где осталась проблема.

Для устранения недостатков стандартных профайлеров многие современные инструменты используют внутреннюю функцию JVM (AsyncGetCallTrace), которая позволяет собирать трассировки стека независимо от безопасных точек. Помимо этого, они объединяют измерение JVM-операций с нативным кодом и системных вызовов операционной системы, так что время, проведенное в сети, ввод/вывод или сборка мусора, также может стать частью flame-графа.

Такие инструменты, как Honest Profiler, perf-map-agent, async-profiler или даже IntelliJ IDEA, умеют захватывать информацию и с легкостью делать flame-графики. 

В большинстве случаев вы просто скачиваете инструмент, предоставляете PID вашего Java-процесса и говорите инструменту работать в течение определенного периода времени и генерировать интерактивный SVG.

# download and unzip async profiler for your OS from:
# https://github.com/jvm-profiling-tools/async-profiler
./profiler.sh -d <duration> -f flamegraph.svg -s -o svg <pid> && \
open flamegraph.svg  -a "Google Chrome"

SVG, создаваемый этими инструментами, не просто красочный, но и интерактивный. Вы можете увеличивать секции, искать посимвольно и т.д. 

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


Интересно развиваться в данном направлении? Запишитесь на бесплатный Demo-урок «Скрипты и сценарии нагрузочного тестирования- Performance center (PC) и Vugen»!

OTUS. Онлайн-образование
Цифровые навыки от ведущих экспертов

Комментарии 9

    0
    Да классная штука эти графики, причём на самом деле с миром Джавы они ни как не связаны, генератор svg представления написан на Перле, ну а информацию на вход ей может предоставлять что угодно, будь то что-то из Джава мира как в этой статье, или Сишная perf из состава ядра Linux.
      0

      Я часто пользуюсь SJK для снятия флейм-графов с джава-приложений. У неё есть несколько достоинств:


      • не обязательно прописывать дополнительные флаги для приложения, то есть можно снимать прямо на проде;
      • не нужен перл-скрипт для получения svg, всё уже есть внутри;
      • кроме svg, она умеет выдавать html+js, в котором можно динамически включать-выключать потоки, или, например, посмотреть более крупно только тот стек вызовов, который нас интересует.

      Из недостатков можно отметить, что стек не будет включать нативные вызовы ОС (зеленая часть на графиках в статье), но для моих задач возможностей SJK было более чем достаточно.

        0
        Достоинств по сравнению с чем?
        Упомянутый в статье async-profiler тоже не требует дополнительных флагов JVM, вносит меньший оверхед при профилирования в проде, тоже сам генерирует flame graph без сторонних перл-скриптов, но при этом показывает нативные стеки и стеки ядра. Но главное, лишён проблемы safepoint bias.
          0

          промахнулся веткой, ответил в общий тред случайно

        +1

        Сразу скажу, что мой ответ не для флейма, я просто постараюсь объяснить свою позицию. Я с большим уважением отношусь и к SJK Алексея, и к вашему, Андрей, async-профайлеру.


        В SJK мне нравится, во-первых, вывод в html+js, он намного удобнее svg. Он, например, позволяет выделить фрейм, и он подсветится в нескольких стек трейсах, и выдаст суммарную частоту, с которой этот фрейм встречался. И это мне действительно было полезно в работе, когда, например, в сумме по трём стэкам один фрейм встречался с частотой в 77%.


        А во вторых, я профилирую энтерпрайз-приложения, которые находятся в зелёной зоне кривой Шипилёва, то есть мне нет никакой необходимости ни в нативных стеках, ни в том, чтобы профайлер был лишён проблемы safepoint bias. Обычно мои перформанс-слонопотамы отнимают 60-80% работы программы. Их с любым профайлером будет видно, просто мне нравятся флейм-графы за их наглядность.

          0
          Без проблем — пользуйтесь, чем нравится. Я, скорее, для себя понять, какие востребованные фичи можно было бы добавить в async-profiler. Просто пока всё, что вы перечислили, в нём тоже есть :)

          Через функцию Search можно так же подсветить фрейм во всех стеках и увидеть суммарный процент. А начиная с версии 1.8, async-profiler умеет генерировать HTML Flame Graph (на основе Canvas) — такой граф рендерится в десятки раз быстрее, чем svg.
            0

            Андрей, приветствую!
            Также пользуюсь SJK, также как и коллега выше работаю с Enterprise-приложениями.


            А async-profiler может формировать отчетность не на станции, на которой выполняется профилирование, а на машине инженера? Не нашел такой возможности изучив документацию

              0
              Не очень понял, в чём проблема. Да, async-profiler может собирать профиль в нескольких форматах, которые потом можно объединять, фильтровать и анализировать на любой другой машине.
              • collapsed — простейший текстовый формат, который тривиально парсить и фильтровать хоть grep'ом;
              • jfr — бинарный формат, совместимый с Java Flight Recorder. Его можно открывать в Mission Control и там уже по-всякому анализировать: по классам, пакетам, потокам, временным интервалам и т. д.

              В обоих этих форматах можно объединить несколько профилей простой конкатенацией файлов.
              +1

              Могу перечислить что нахожу удобным в SJK.


              • Неплохая документация. Нет большого количества примеров, часть примеров использования пришлось в свое время подсматривать в тестах инструмента, но она неплохая.
              • Явное разделение на процесс сбора метрик и процесс формирования отчета по метрикам. Что очень удобно.
              • Работа с Windows и Linux, успешно профилировал службы на JVM 6 для Windows (и они были запущены от SYSTEM, это был отдельный квест), все получилось
              • Удобный вывод в виде CSV и текстовых файлов легко передается в InfluxDB, что позволяет организовать непрерывный мониторинг с отображением результатов в Grafana
              • Механизм фильтров и опция categorize для меня является очень удобной фичей, позволяя превратить результаты профилирования в статистику, но вот как раз по ней лучшей документацией являются тесты, а сама документация пока непонятная
              • Возможность объединить результаты профилирования с нескольких POD-ов/экземпляров приложения в один отчет

              За счет фильтров, возможности отдельно собрать sdt-файл статистики и отдельно сформировать отчетность в разной форме от csv до svg и html, возможности работы на Windows/Linux/MacOS сделал удобный способ профилирования:


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

              Отчеты формируются сложные и долго, по 15-20 минут: объединение результатов профилирования с разных POD-ов микросервисов, с использованием массы фильтров — по потокам, по методам сервиса, по отдельным узким местам. Поэтому удобно, что это делается не на самой POD-е, а на моей машине.


              Сложности SJK — нет пока документации на categorize, кроме самих исходников:



              Сложности SJK — не запустить профилирование, если есть только JRE, а нет JDK/JDK-devel


              • К счастью. В базовых образах Docker, используемых разработчиками на текущем проекте, есть jdk-devel, поэтому SJK тут работает без дополнительных yum install или apk…
              • Но если бы в контейнерах был бы только JRE, было бы здорово, чтобы инструмент профилирования мог нести с собой tools.jar или какой-то другой механизм подключаться к JRE-процессам, а не только к JDK/JDK-devel-процессам

              Раньше наличие только JRE на станции, где нужно выполнить профилирование, было проблемой. Когда надо было профилировать на продуктиве, а там не было возможности поставить что-то дополнительное — нет прав на это. И приходилось копировать вместе с sjk на станцию и папку с jdk — на Windows способ работает хорошо, а вот на Linux нет одной папки с jdk-devel, там нужны и нативные библиотеки и около 5-6-ти разных пакетов, в общем, не просто

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

          Самое читаемое