kill -3, чтобы получить дамп потока Java

116

Я использую kill -3команду, чтобы увидеть дамп потока JVM в unix. Но где я могу найти вывод этой killкоманды? Я потерян!!

javanerd
источник
Какой процесс вы убиваете? Это сервер приложений J2EE? Если это так, вы должны найти трассировку стека в стандартном выпуске.
Лучано Фиандезио 02
Я
убиваю
2
Не стоит писать дамп потока на консоли. так как класс java имеет консоль как стандартный вывод
javanerd

Ответы:

194

В качестве альтернативы вы можете использовать jstack (входит в состав JDK), чтобы получить дамп потока и записать результат в любом месте. Разве это не доступно в среде unix?

jstack PID > outfile
Джошуа Маккиннон
источник
1
Да - в тот момент, когда он запущен. Вы также можете указать -l (нижний регистр L) для длинного списка, который выводит дополнительную информацию о блокировках
Джошуа Маккиннон
2
Пока команда jstack не дает стабильного сбоя из-за «Невозможно определить тип потока из адреса»
;-(
1
Если вы видите эту ошибку, я предлагаю обсудить ее с вашим поставщиком. Быстрый поиск показывает, например, что в RHEL есть открытая ошибка, касающаяся этой ошибки и openjdk ...
Джошуа Маккиннон
7
Стоит отметить, что jstack требует JDK. Если вы запускаете приложения на сервере, на котором установлена ​​только JRE, вам нужно будет найти другое средство для сброса потоков.
jeffkempf
1
Вот как использовать jstack для получения дампа потоков процесса работает под другим пользователем, как окна обслуживания: stackoverflow.com/questions/1197912/...
Vadzim
44

Дамп потока записывается в систему из виртуальной машины, на которой вы выполнили kill -3. Если вы перенаправляете вывод консоли JVM в файл, дамп потока будет в этом файле. Если JVM работает в открытой консоли, дамп потока будет отображаться в ее консоли.

Крис Бабич
источник
1
Существует способ перенаправить вывод дампа потока JVM в отдельный файл. Смотрите в моем ответе.
Vadzim
32

Существует способ перенаправить вывод дампа потока JVM при сигнале прерывания в отдельный файл с помощью диагностической опции LogVMOutput :

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log
Vadzim
источник
5
Технически это не «перенаправляет» вывод дампа потока. Он включает регистрацию JVM в jvm.log (который включает вывод дампа потока), но kill -QUIT все равно будет выгружать в стандартный вывод процесса (также). Проголосовали за описание непонятных параметров JVM :)
sqweek
25

С Java 8 на картинке jcmdэто предпочтительный подход.

jcmd <PID> Thread.print

Ниже приведен фрагмент документации Oracle :

В выпуске JDK 8 представлены Java Mission Control, Java Flight Recorder и утилита jcmd для диагностики проблем с JVM и приложениями Java. Рекомендуется использовать последнюю версию утилиты jcmd вместо предыдущей утилиты jstack для расширенной диагностики и снижения накладных расходов на производительность.

Однако доставка этого вместе с приложением может иметь последствия для лицензирования, в чем я не уверен.

Арнаб Бисвас
источник
1
К сожалению , jcmdне удается подключиться к процессу обслуживания окна с com.sun.tools.attach.AttachNotSupportedException: Insufficient memory or insufficient privileges to attachпока jstack -Fпреуспевает: stackoverflow.com/questions/1197912/...
Вадима
1
Вам нужно запустить jcmd <pid> Thread.dump под тем же пользователем, что и java-процесс, иначе ваши соединения будут отключены. См stackoverflow.com/questions/25438983/...
Twilite
11

В том же месте, где размещен стандартный вывод JVM. Если у вас есть сервер Tomcat, это будет catalina_(date).outфайл.

Даниил
источник
8

При использовании kill -3 в стандартном выводе должен отображаться дамп потока. Большинство серверов приложений записывают стандартный вывод в отдельный файл. Вы должны найти его там, используя kill -3. Есть несколько способов получить дамп потоков:

  • kill -3 <PID>: Выводит вывод на стандартный вывод.
  • Если у вас есть доступ к окну консоли, в котором работает сервер, можно использовать Ctrl+Break комбинацию клавиш для генерации трассировки стека на STDOUT.
  • Для виртуальных машин хот-спотов мы также можем использовать jstackкоманду для создания дампа потока. Это часть JDK. Синтаксис следующий:

    Usage:
    
    jstack [-l] <pid> (to connect to running process)
    jstack -F [-m] [-l] <pid>(to connect to a hung process)
    
     - For JRockit JVM we can use JRCMD command which comes with JDK Syntax: 
       jrcmd <jrockit pid> [<command> [<arguments>]] [-l] [-f file] [-p] -h]
Apoorve
источник
У меня проблемы с использованием Kill -3 <PID>. Он работает нормально, но убивает процесс также после записи дампа потока на консоль. Он должен это делать?
Эшли
@Ashley - нет, не kill -3 <PID>следует убивать JVM. Какой тип Java-приложения вы ищете?
ОДС
2

В Jboss вы можете выполнить следующее

nohup $JBOSS_HOME/bin/run.sh -c  yourinstancename $JBOSS_OPTS >> console-$(date +%Y%m%d).out  2>&1 < /dev/null &
kill -3 <java_pid>

Это перенаправит ваш вывод / поток на консоль файла, указанную в приведенной выше команде.

Аниш
источник
2
  1. Найдите идентификатор процесса [PS ID]
  2. Выполнить jcmd [PS ID] Thread.print
Мехмет Эрдемсой
источник
2

Действия, которые следует выполнить, если вы хотите получить дамп потока автономного Java-процесса

Шаг 1. Получите идентификатор процесса для сценария оболочки, вызывающего java-программу.

linux$ ps -aef | grep "runABCD"

user1  **8535**  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh

user1 17796 17372   0 08:15:41 pts/49      0:00 grep runABCD

Шаг 2: Получите идентификатор процесса для дочернего процесса, который был вызван runABCD. Используйте указанный выше PID, чтобы получить дочерние элементы.

linux$ ps -aef | grep **8535**

user1  **8536**  8535   0   Mar 25 ?         126:38 /apps/java/jdk/sun4/SunOS5/1.6.0_16/bin/java -cp /home/user1/XYZServer

user1  8535  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh

user1 17977 17372   0 08:15:49 pts/49      0:00 grep 8535

Шаг 3: Получите JSTACK для конкретного процесса. Получите идентификатор процесса вашего процесса XYSServer. т.е. 8536

linux$ jstack **8536** > threadDump.log
Ник
источник