Что такое утилита `jstack` в Java и для чего она применяется?

«Что такое утилита `jstack` в Java и для чего она применяется?» — вопрос из категории DevOps, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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"

Важные замечания:

  1. Для выполнения jstack требуются те же права пользователя, что и у целевого процесса Java.
  2. В современных версиях Java предпочтительнее использовать jcmd — универсальный инструмент:
    jcmd <pid> Thread.print
  3. Для полного анализа производительности jstack следует сочетать с профилировщиками (Async Profiler, VisualVM) и метриками ОС (top, pidstat).