Ответ
jstack — это диагностическая утилита командной строки из JDK для получения дампа потоков (thread dump) работающего процесса Java. Она показывает состояние всех потоков JVM, включая их стектрейсы и информацию о блокировках.
Основное назначение: Анализ проблем с производительностью и зависаниями:
- Обнаружение deadlock'ов (взаимных блокировок потоков).
- Диагностика "подвисаний" приложения (потоки в состоянии
WAITING,BLOCKED). - Выявление высокой загрузки CPU (поиск потоков в состоянии
RUNNABLE, выполняющих циклы).
Базовые команды:
# Получить PID процесса Java
jps -l
# Снять дамп потоков и сохранить в файл
jstack <pid> > thread_dump.txt
# Снять дамп с дополнительной информацией о синхронизаторах
jstack -l <pid> > thread_dump_with_locks.txt
Пример анализа deadlock в выводе jstack:
Утилита явно укажет на проблему:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f... (object 0x00000000..., a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007f... (object 0x00000000..., a java.lang.Object),
which is held by "Thread-1"
Важные замечания:
- Для выполнения
jstackтребуются те же права пользователя, что и у целевого процесса Java. - В современных версиях Java предпочтительнее использовать
jcmd— универсальный инструмент:jcmd <pid> Thread.print - Для полного анализа производительности
jstackследует сочетать с профилировщиками (Async Profiler, VisualVM) и метриками ОС (top, pidstat).
Ответ 18+ 🔞
Слушай, а вот этот ваш jstack — это же просто палочка-выручалочка, когда приложение вдруг встаёт как вкопанное и начинает жрать процессор, как голодный студент доширак! По сути, это такая консольная штука из JDK, которая вытряхивает из работающей Java-машины дампик всех потоков (thread dump). Она тебе вывалит на экран, чем занят каждый поток: где он торчит, на каком методе завис, и за какую блокировку дерётся с соседом.
Зачем это, спросишь? Да чтобы головную боль лечить!
- Найти deadlock'и — когда два потока друг друга ждут, как два упрямых барана, и оба нихуя не работают. Классика!
- Понять, почему всё «подвисло» — посмотреть, какие потоки в состоянии
WAITINGилиBLOCKEDи чего они, блядь, ждут. - Выяснить, кто CPU жрёт — отыскать те самые прожорливые потоки в статусе
RUNNABLE, которые в бесконечном цикле какую-то хуйню крутят.
Как этим пользоваться, не сломав ничего?
# Сначала узнаём PID нашего страдающего процесса
jps -l
# А потом снимаем с него дамп, как слепок с преступника, и пишем в файлик
jstack <pid> > thread_dump.txt
# Можно и с дополнениями про локсы, если подозреваешь неладное
jstack -l <pid> > thread_dump_with_locks.txt
А вот, смотри, как jstack deadlock прямо в лоб ловит — красота же!
Found one Java-level deadlock:
=============================
"Thread-1":
ждёт, пока освободится монитор 0x00007f... (объект 0x00000000...),
а его держит "Thread-0"
"Thread-0":
ждёт, пока освободится монитор 0x00007f... (объект 0x00000000...),
а его держит "Thread-1"
Ёпта, да они друг друга в петлю загнали! Прямо как в том анекдоте.
Но есть важные нюансы, блядь!
- Запускать
jstackнужно от того же пользователя, под которым бежит сам Java-процесс, иначе получишь по рукам. - Сейчас модно и правильно использовать
jcmd— это такой швейцарский нож вместо кучи отдельных отвёрток:jcmd <pid> Thread.print - Не стоит думать, что
jstack— волшебная таблетка. Для полной картины его надо с профилировщиками (типа Async Profiler) скрещивать да на метрики операционки (top,pidstat) смотреть. А то так и до ебаного микросервисного колдовства недалеко.