В 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. Достаточно задать нужный фильтр, чтобы точно знать, где и когда выполняется нужный метод.