Как собрать стэк-трейсы конкретных тредов с sample interval ± 100ms

Есть OpenJDK8.
Есть пул потоков ExecutorService к примеру размером 40.
Принцип работы такой:
1)пришел запрос, для его обработки берется поток из пула.
2)во взятом потоке обрабатываем запрос
3)поток возвращается в пул потоков.
И так "по кругу".

Потоки на протяжении жизни JVM остаются одни и те же(имена потоков не меняется, уникальны).

Необходимо как-то понять, чем занимался каждый из этих потоков, с частотой сэмплирования к примеру 100ms. Фактически просто записать в файл все стектрейсы потоков.

Различные профайлеры измеряют cpu, allocation и т.п., агрегируют потоки, убирают простаивающие. Но как просто записать стек-трейсы я не нашел.(Смотрел в том числе async-profiler Андрея Паньгина).

За исключением SJK от Алексея Рогозина, но несмотря на то, что я указывал частоту обновления -i 100ms, снятие происходило приблизительно раз в секунду и RMI тред потреблял одно ядро CPU на 90%.


Ответы (1 шт):

Автор решения: apangin

async-profiler в режиме wall clock делает ровно то, что нужно.

profiler.sh -e wall -i 100ms -d 60 -f out.jfr PID
  • -e wall выбирает режим wall clock (сэмплирование всех тредов)
  • -i 100ms задаёт интервал
  • -d 60 продолжительность профилирования в секундах
  • -f out.jfr записывать неагрегированные данные в JFR формате, который потом можно открыть в Java Mission Control

Недавно в ветку thread-filter закоммитил фикс, который динамически подбирает частоту сэмплирования, чтобы максимально точно выдерживать указанный интервал, независимо от количества тредов.

→ Ссылка