Команда Spring АйО провела небольшое исследование JEP 520. В Java 25 JFR (Java Flight Recorder) позволит точно отслеживать выполнение конкретных методов — без изменения исходников, без логирования и без сторонних Java-агентов.
? Зачем это нужно?
Допустим, приложение долго стартует или внезапно теряет соединения с БД. Раньше приходилось:
- Логировать вручную 
- Добавлять JFR-события в код 
- Подключать агент через - -javaagent
- Пытаться угадать с sampling-профайлером 
- Использовать Spring AOP и - @Around-аспекты
Теперь всё можно сделать проще: точно, из коробки и с минимальной настройкой.
⚙️ Что добавили?
Два новых события в JFR:
- jdk.MethodTiming— считает вызовы, замеряет среднее, мин/макс время выполнения
- jdk.MethodTrace— пишет стек вызова и длительность каждого вызова
И самое главное: всё настраивается фильтрами, без изменений в коде!
? Пример использования
Допустим, вы хотите посмотреть, как часто и как долго вызывается HashMap::resize.
Запуск:
java -XX:StartFlightRecording=method-trace=java.util.HashMap::resize,filename=resize.jfr ...Анализ:
jfr print --events jdk.MethodTrace resize.jfrПример вывода:
jdk.MethodTrace {
    startTime = 00:39:26.379
    duration = 0.00113 ms
    method = java.util.HashMap.resize()
    eventThread = "main"
    stackTrace = [
      java.util.HashMap.putVal(...)
      java.util.HashMap.put(...)
      ...
      java2d.J2Ddemo.main(String[]) line: 674
    ]
}Как ещё можно использовать?
Замерить все <clinit> и понять, что тормозит:
-XX:StartFlightRecording:method-timing=::<clinit>,filename=init.jfrОтслеживать методы с аннотацией @Get из JAX-RS:
jcmd <pid> JFR.start method-timing=@jakarta.ws.rs.GETСравнивать, сколько раз и с каким временем выполнялся метод:
<setting name="filter">
  com.example.Foo::doSomething;
  com.example.Bar::handle
</setting>Какой результат?
После запуска вы получаете .jfr-файл, который можно:
- Просмотреть через - jfr printили- jfr view
- Подгрузить в JDK Mission Control 
- Анализировать удалённо через JMX/RemoteRecordingStream 
В чём польза?
- Быстро находим горячие методы 
- Точно отслеживаем, что вызывает - FileDescriptor::close
- Проверяем гипотезу, стал ли метод быстрее после оптимизации 
- Отлаживаем проблемы без доступа к коду сторонних библиотек 
Вывод
Можно будет не модифицировать код, городить прокси или запускать -javaagent. Достаточно задать нужный фильтр, чтобы точно знать, где и когда выполняется нужный метод.

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано
Комментарии (3)
 - TimurZhoraev01.08.2025 16:27- Профайлинг по времени должен быть более тонким, например, для стека вызовов/данных особенно для рекурсивных функций, она может съедать такты, плюс в некоторых случаях если есть цепочка длинных особенно множественных наследований. Указатель на указатель итд перед вызовом короткой функции в этом варианте обычное дело и может съесть довольно много за счёт не последовательного доступа в память. Хотя это тёмная сторона всех дебаггеров - учёт времени не только тела функции но и подготовки аргументов, восстановления регистров/стека, возврата, а если это всё ещё сдобрено вложенными прерываниями. 
 - yrub01.08.2025 16:27- на сколько помню еще в другом jep обещают нормальный трекинг: можно определять контекст и по нему понимать что к какой "транзакции" относится. этого не хватало изначально 
 
           
 
lsillarionov
Выглядит как очень удобная штука. Может забрать на себя часть задач, решаемых при помощи async-profiler