Gymterview
middle

Как получить дамп потока?

Дамп потока (thread dump) – это снимок состояния всех потоков JVM в определённый момент времени. Он содержит имена потоков, состояния, стеки вызовов и информацию о блокировках. Дамп потока – основной инструмент диагностики deadlock’ов, livelock’ов, зависаний и высокой нагрузки CPU.

Важно: не путайте thread dump (дамп потоков) и heap dump (дамп кучи). Thread dump показывает, что делают потоки. Heap dump показывает содержимое памяти (объекты).

Способы получения thread dump

1. Клавиатурная комбинация / сигнал ОС

Платформа Способ
Windows Ctrl+Break в консоли приложения
Linux / macOS kill -3 <PID> или kill -QUIT <PID>

Дамп выводится в stdout (или в лог-файл, если stdout перенаправлен).

2. Утилита jstack

Пример
jstack <PID>                    # Обычный дамп
jstack -l <PID>                 # Расширенный (с информацией о блокировках)
jstack -F <PID>                 # Принудительный (если JVM не отвечает)

3. Утилита jcmd (рекомендуемый способ с Java 8+)

Пример
jcmd <PID> Thread.print         # Дамп потоков
jcmd <PID> Thread.print -l      # С информацией о блокировках

4. Программно через ThreadMXBean

Пример: получение thread dump из кода
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class ThreadDumpUtil {
    public static String getThreadDump() {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        ThreadInfo[] infos = bean.dumpAllThreads(
            true,  // lockedMonitors
            true   // lockedSynchronizers
        );

        StringBuilder sb = new StringBuilder();
        for (ThreadInfo info : infos) {
            sb.append(info.toString());
        }
        return sb.toString();
    }

    // Обнаружение deadlock
    public static long[] detectDeadlocks() {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        return bean.findDeadlockedThreads(); // null если deadlock нет
    }
}

5. Через JConsole / VisualVM / JMC

Графические инструменты мониторинга JVM позволяют получить thread dump через GUI:

  • JConsole – вкладка «Threads», кнопка «Detect Deadlock»
  • VisualVM – вкладка «Threads», кнопка «Thread Dump»
  • Java Mission Control (JMC) – через Flight Recorder

6. Через IDE

IntelliJ IDEA, Eclipse и другие IDE позволяют получить thread dump запущенного приложения через меню отладки.

Как читать thread dump

Пример
"main" #1 prio=5 os_prio=0 tid=0x00007f... nid=0x1a03 waiting on condition [0x00007f...]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at com.example.MyApp.main(MyApp.java:15)
Поле Значение
"main" Имя потока
#1 Номер потока
prio=5 Java-приоритет
tid ID потока в JVM
nid Нативный ID потока в ОС
Thread.State Состояние потока (RUNNABLE, WAITING, BLOCKED и т.д.)

Способы получения heap dump (дампа кучи)

Для полноты – способы получения дампа кучи (отдельный инструмент диагностики):

  • jmap -dump:format=b,file=heap.hprof <PID> – создание дампа
  • -XX:+HeapDumpOnOutOfMemoryError – автоматический дамп при OutOfMemoryError
  • jcmd <PID> GC.heap_dump filename.hprof – через jcmd

Аналогия из жизни. Thread dump – это фотография всех сотрудников офиса в определённый момент: кто работает, кто ждёт в очереди к принтеру, кто заснул. По этой фотографии можно понять, почему работа не движется (deadlock) или почему один сотрудник постоянно занят (высокая нагрузка CPU).

На собеседовании. Назовите минимум 3 способа: (1) jstack <PID>, (2) kill -3 <PID> (Linux), (3) ThreadMXBean программно. Не путайте thread dump и heap dump – это разные вещи. Упомяните, что ThreadMXBean.findDeadlockedThreads() позволяет программно обнаруживать deadlock’и. В production рекомендуется настроить -XX:+HeapDumpOnOutOfMemoryError и иметь скрипт для снятия thread dump.