Профилирование (JFR, async-profiler)
Тема дорожной карты · Java
Профилирование Java — это систематический процесс измерения использования CPU, выделения памяти, активности потоков, поведения GC и конкуренции за блокировки в работающем JVM-приложении для выявления узких мест производительности и направления усилий по оптимизации. JDK поставляется со встроенной инфраструктурой профилирования: jcmd отправляет диагностические команды живой JVM, jstack захватывает дампы потоков для анализа конкурентности, jmap производит дампы кучи для расследования утечек памяти, а jstat транслирует статистику GC — всё это без каких-либо изменений в приложении. Промышленные инструменты профилирования Java включают JDK Mission Control (JMC) в паре с Java Flight Recorder (-XX:+FlightRecorder), async-profiler (низкоуровневое профилирование CPU и выделений памяти через AsyncGetCallTrace) и YourKit или встроенный профилировщик IntelliJ IDEA — каждый предлагает flame-графики и тепловые карты выделений, раскрывающие горячие пути JIT-компиляции, давление GC и конкуренцию за блокировки в нагрузках Spring, Hibernate и JDBC. API ManagementFactory в java.lang.management предоставляет программный доступ к ThreadMXBean, MemoryMXBean и GarbageCollectorMXBean для встраивания лёгких метрик профилирования непосредственно в эндпоинты состояния приложения. Эффективное профилирование Java неотделимо от знания внутреннего устройства JVM — понимание того, как JIT-компилятор HotSpot оптимизирует код, как работают поколения GC и чем Virtual Threads отличаются от платформенных потоков, обязательно для интерпретации вывода профилировщика и принятия обоснованных решений по настройке.
Как это работает
Профилирование (JFR, async-profiler) покрывает class loading (Bootstrap, Platform, Application classloaders), байткод (JIT-компилируется HotSpot C1/C2 или AOT через GraalVM), GC (G1 — дефолт 9+; ZGC + Shenandoah — low-pause; Parallel — throughput), memory areas (heap, metaspace, stack, native), JFR (Java Flight Recorder) — production-профайлинг, jstack/jmap/jstat — CLI-тулзы.
Когда применять
Тюньте heap (-Xms = -Xmx для предсказуемой аллокации; размер = ~60-80% доступной RAM в контейнере). G1 GC — кроме нужды в очень низких паузах (тогда ZGC или Shenandoah). Гоняйте JFR непрерывно в production с низким overhead — бесценно, когда что-то идёт не так. jcmd — для взаимодействия с живой JVM. Читайте GC-логи (-Xlog:gc*:file=gc.log).
Типичные ошибки
Ловушки Профилирование (JFR, async-profiler): дефолтный -Xmx 256MB или 25% RAM хоста (часто мал — задавайте явно); выбор CMS GC (deprecated, удалён); игнор native-памяти (off-heap buffers, JNI) когда total memory > heap; запуск профайлера без warmup (JIT-warmup искажает цифры).