ТОП Інструментів глибинного профайлінгу JVM: чим реально копати продуктивність, коли “просто додай кеш” вже не працює

Comments · 299 Views

Профайлер — це твій рентген, МРТ і інколи судово-медичний експерт. Він показує, де саме JVM їсть CPU/памʼять/локи/час, а не де менеджер “відчуває”.

Профайлер — це твій рентген, МРТ і інколи судово-медичний експерт. Він показує, де саме JVM їсть CPU/памʼять/локи/час, а не де менеджер “відчуває”.
Правильний інструмент = менше героїзму вночі, менше чату з токсичним PM, більше грошей і спокою.
Нормальна зв’язка сьогодні: JFR/JMC + async-profiler. Вони дають low-overhead знімки навіть на prod. 

Інструменти JVM Profiling

ІнструментТип / фокусОверхедProd‑safeСильна сторонаКоли брати
Java Flight Recorder (JFR)CPU / heap / locks / GC / eventsнизькийтакВбудований у JDK, дуже деталізовані події JVMМайже завжди, особливо прод
JDK Mission Control (JMC)GUI для JFR + аналіз—такГлибока зручна візуалізація JFRКоли треба не лише "зняти", а й зрозуміти
async‑profilerCPU / alloc / locks + flamegraphsнизькийтак / обережноНема safepoint‑bias, бачить native/GC/JITКоли треба швидко та чесно знайти hotspot
IntelliJ IDEA ProfilerIDE‑профайл (JFR+async)низькийобережно"Два кліки і готово" у IDEЛокально / стейдж
VisualVMCPU / heap / threadsсереднійобережноПростий GUI, все в одномуШвидкий огляд сервісу без комерції
YourKit Java ProfilerCPU / heap / threads / IOсереднійчасто такДуже сильний heap/alloc аналізКоли пахне витоком памʼяті або алокаціями
JProfilerCPU / heap / threads / DB / IOсереднійчасто такГлибокі probes, історичні знімкиКоли треба розтинання "по шарах"
Datadog Continuous ProfilerContinuous CPU / alloc / locksнизькийтакПостійний профайлінг на проді (JFR-based)Мікросервіси, latency‑полювання, SLO
New Relic Real‑time ProfilerContinuous JFRнизькийтакВмикається та тюниться на льотуКоли прод "горить", а рестарт табу
Grafana Pyroscope (Java)Continuous flamegraphsнизькийтакЗберігає профілі як часовий рядБачити деградацію після релізів
Google Cloud ProfilerCPU / heap / alloc (continuous)низькийтакХмарний профайлер зі статистичним семплюваннямЯкщо вже в GCP та нема часу на DIY
Arthas (Alibaba)trace / watch / profilerнизькийобережноЖиві діагностики у рантайміSSH є, IDE нема
jcmd / jstack / jmap / jstatJDK CLI діагностиканизькийтак"Швейцарський ніж" JDKКоли треба швидко зібрати факти в проді
Eclipse MATHeap dump analysis—такКороль аналізу hprofПісля OOM або дивних утримань обʼєктів
HPROF heap dumpsДампи памʼятівисокийобережноСирі дані для MAT / YourKitКоли інше не показує, хто жере heap
Honest ProfilerCPU samplingнизькийобережноАльтернатива async‑profilerКоли треба незалежну перевірку
perf‑map‑agent + Linux perfNative CPU profilingнизький / середнійобережноІдеально для JNI / kernelКоли підозра, що JVM не винна
Elastic Universal Profiling + APMContinuous host‑levelнизькийтакКореляція трас і CPUКоли треба "видно все в одному місці"
GlowrootAPM + samplingсереднійобережноПростий self‑hosted UIМалий проєкт, потрібен APM "з коробки"
AppDynamicsAPM + snapshotsсереднійтак (платно)Глибокий аналіз транзакційЯкщо ентерпрайз вже купив
DynatraceAPM + continuous profilingнизький / середнійтак (платно)Автоінтеграції, smart baselinesКоли DevOps живе у Dynatrace
JITWatchJIT / компіляція—такПояснює, чому JIT не оптимізуєКоли код "ок", а швидкість ні
GCViewer / GCEasyGC logs analysis—такЛюдський розбір GC‑пеклаКоли latency стрибає через GC
jHiccupPauses / latencyнизькийтакЛовить JVM hiccupsКоли SLA про плавність важливіші throughput
JDK25 CPU‑time ProfilerНовий семплер CPU‑timeнизькийобережноМенше шуму, точніші виміри CPUЯкщо ти на JDK25+
DJXPerf / OJXPerfPMU‑based memory/object profilingнизький/середнійобережноДуже глибокі memory‑інсайтиДля performance‑маніяків та R&D

 

Порівняння

  • JFR/JMC — як штатний лікар у поліклініці: завжди поруч, дешевий (бо безкоштовний), даних море, оверхед мінімальний. Якщо не знаєш з чого почати — починай з нього. 

  • async-profiler — як приватний хірург, який робить розтин швидко і без ілюзій. Flamegraph — це взагалі найкращий формат, щоб “побачити біль”. 

  • VisualVM/IDE-профайлери — норм для локалки і стейджа. На проді можуть влаштувати “ще один інцидент заради інциденту”.

  • YourKit/JProfiler — топові комерційні “комбайни”. Коштують, але часто економлять дні життя. Особливо коли heap/alloc історія складна.

  • Continuous profilers (Datadog, Pyroscope, Cloud Profiler, New Relic) — це коли ти не хочеш ловити баг раз на місяць вручну, а хочеш бачити деградацію після кожного релізу. Дуже розробницька штука, хай опси і кривляться. 

Маленький холодний душ: будь-який профайлер може брехати (семплінг, bias, оптимізації JIT). Тому “перевіряй двома інструментами і головою”. 


Best practices

  • Спочатку low-overhead семплінг (JFR або async-profiler). Не лізь одразу в інструментацію, якщо не хочеш зловити Heisenbug.

  • Профайл під реальним навантаженням. Локалка без трафіку — це як міряти витрату бензину на домкраті.

  • Фіксуй baseline до оптимізацій. Інакше ти “покращиш” те, що й так було норм.

  • Дивись не тільки CPU. 50% прод-проблем — це алокації, GC і lock contention, а не “повільний метод”. 

  • Знімай короткі профілі по 30–120 секунд і кілька разів. Довгі записи — сміття, яке ніхто не розбере (включно з тобою через тиждень).

  • Для прод-інцидентів — continuous або on-the-fly JFR. Краще мати профіль до фіксу, ніж героїчну легенду після. 


Типові помилки

  • Плутати throughput і latency. “Середній час ок” не означає, що у 1% користувачів не пекло.

  • Оптимізувати те, що займає 2% CPU. Це класика жанру “чисто щоб було чим зайнятись”.

  • Вірити першому графіку. Профайл — це гіпотеза, а не вирок.

  • Профайлити з debug-логами і feature-flags-парадом. Потім дивуєшся, що “все повільне”.

  • Запускати інструментаційний профайлер на проді в піковий час. Так ти станеш причиною інциденту, який профайлите. ;)


Сценарії, де це реально рятує життя

  • “Після релізу CPU 90%, але графіки APM нічого не кажуть.” JFR/async показують конкретний hot path.

  • “Латентність стрибає раз на 5 хвилин.” GC logs + JFR pauses + jHiccup ловлять винний тип пауз.

  • “OOM зʼявляється тільки на проді.” Heap dump + MAT/YourKit показують retention chain і хто тримає обʼєкти як токсичний колега — “я просто запитав”.

  • “Усе ніби fast, але сервіс тупо не масштабується.” Lock profiling в JFR/async виявляє один невинний synchronized, який тримає світ на плечах.

  • “Підозра на JNI або драйвери.” perf + perf-map-agent показують, що в JVM взагалі все нормально, а горить у native. 


Чеклист - як вибрати інструмент

1. Де саме болить?

Спочатку не кидайся до інструментів — зафіксуй симптом, тоді вибір майже сам себе зробить.

CPU або latency скачуть?
– Бери JFR (стабільно, безпечно, глибоко) або async-profiler (швидко, чесно, жорстко).
– Якщо “щось дивно підвисає раз на 2 секунди” — async-profiler покаже це краще за всіх.

Памʼять тікає, heap пухне?
– YourKit, якщо хочеш красивий UI і глибокий аналіз.
– Eclipse MAT, якщо треба «слідчий з лупою».
– Якщо пахне OOM — роби heap dump, іншого шляху нема.

Потоки блокуються, дедлоки, lock contention?
– JFR + lock events — золото.
– async-profiler також уміє показувати lock contention.

GC забирає всю увагу замість твоєї команди?
– Проганяєш логи через GCViewer або GCEasy,
– А потім дивишся JFR-події, щоб зрозуміти контекст.


2. Це прод чи стейдж?

Тут усе просто й суворо, як бюджетний код-рев’ю.

Прод
– JFR — майже безгрешний.
– async-profiler — можна, але з розумом (sampling mode).
– Datadog / Pyroscope / Cloud Profiler — для команд, де “історія продуктивності” — must have.

Стейдж або локалка
– Можна хоч IntelliJ Profiler, хоч VisualVM.
– Не переживай, якщо вони дадуть 5–10% оверхеду — тут це ок.


3. Скільки маєш часу на розбір?

Вибір інструменту сильно залежить від того, що в тебе сьогодні: дедлайн чи плед.

Є 10 хвилин і треба щось довести?
– async-profiler (+ flamegraph) і ти вже бачиш корінь зла.
– Це “скальпель”, який дає висновок без довгих церемоній.

Є вечір і бажання розібрати до молекул?
– JFR + JMC — і ти вже археолог JVM.
– CPU, GC, locks, IO, контекст подій — все розкладено.


4. Потрібно зрозуміти коли почалася деградація?

Тут одноразові профілі не допоможуть. Треба історія.

Так?
– Datadog Continuous Profiler,
– Grafana Pyroscope,
– Google Cloud Profiler.

Ці хлопці не знімають профіль «коли руки дійшли».
Вони збирають його 24/7 і показують тренди, які важливіші за разовий snapshot.


5. Треба доказати менеджеру, що проблема не в “повільному програмісті”?

Вітаю, ти не перший.

Кращий спосіб довести правду — принести цифри, не емоції.

– Збережи JFR-файл.
– Збережи flamegraph з async-profiler.
– Покажи, що 80% часу йде в ORM, GC, проксі, непотрібні алокації або зовнішній сервіс.

Це працює краще, ніж пів години спорів у Slack.
Умовний flamegraph з двома червоними стовпами — найпереконливіший аргумент у айтішному світі.


Менеджер: “Давайте оптимізуємо все, що повільне.”

Профайлер: “Ось топ-3 методи, що зʼїдають 78% часу.”

Менеджер: “Нє, давайте перепишемо весь сервіс на Rust, бо тренд.”

Ти: “Так, звісно… але спочатку я виправлю цей один рядок.”

Після фіксу мінус 40% CPU.

Менеджер: “Ми завжди вірили в інженерний підхід.”

Ти: “Ага.” :)


 
 
Comments