Всем снова привет! Приглашаем на онлайн-встречу с Василием Кудрявцевым (директором департамента обеспечения качества в АО «РТЛабс»), которая пройдёт в рамках курса «Нагрузочное тестирование». И публикуем перевод статьи Michael Hunger — software developer and editor of Neo4j Developer Blog and GRANDstack!
Стандартные профайлеры Java используют либо инструментарий байткода, либо сэмплинг (рассматривая трассировки стека через короткие промежутки времени), чтобы определить, где было потрачено время. В обоих подходах есть свои недостатки и странности. Понимание результатов работы таких профайлеров само по себе искусство и требует большого опыта.
К счастью, Брендан Грегг, инженер по производительности в Netflix, придумал flame-графики, гениального вида диаграммы для трассировки стека, которые можно собрать практически из любой системы.
Flame-график сортирует и агрегирует трассировки на каждом уровне стека, таким образом их количество отражает процент от общего времени, затраченного в этой части кода. Визуализация этих блоков в виде прямоугольников с шириной, пропорциональной проценту от общего времени работы и укладка их друг на друга оказалась крайне полезной визуализацией. (Обратите внимание на то, что порядок слева направо не имеет принципиального значения, часто это просто сортировка по алфавиту. То же самое и с цветами. Значение имеют только относительная ширина и глубина стека)
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»!