kill -3 para obter java thread dump

116

Estou usando o kill -3comando para ver o despejo de thread da JVM no Unix. Mas onde posso encontrar a saída desse killcomando? Eu estou perdido!!

javanerd
fonte
Qual processo você está matando? É um servidor de aplicativo J2EE? Se for o caso, você deve encontrar o rastreamento de pilha na saída padrão.
Luciano Fiandesio
Estou eliminando um processo que executa a classe java
javanerd
2
Isso não deveria escrever o despejo de thread no console. já que a classe java tem console como std out
javanerd

Respostas:

194

Você também pode usar jstack (incluído com o JDK) para fazer um despejo de thread e gravar a saída onde quiser. Isso não está disponível em um ambiente unix?

jstack PID > outfile
Joshua McKinnon
fonte
1
Sim - no momento em que é executado. Você também pode especificar -l (L minúsculo) para uma lista longa que imprime informações de bloqueio adicionais
Joshua McKinnon
2
Até que o comando jstack falhe consistentemente devido a "Incapaz de deduzir tipo de thread do endereço"
;-(
1
Se você está vendo esse erro, sugiro levá-lo ao seu fornecedor. Uma pesquisa rápida mostra, por exemplo, há um bug aberto no RHEL em relação a este erro e openjdk ...
Joshua McKinnon
7
É importante notar que o jstack requer o JDK. Se você estiver executando aplicativos em um servidor que possui apenas o JRE instalado, você precisará encontrar outro meio de despejo de thread.
jeffkempf
1
Aqui está como usar o jstack para obter o despejo do thread de um processo em execução em um usuário diferente, como o serviço do Windows: stackoverflow.com/questions/1197912/…
Vadzim
44

O despejo de thread é gravado no sistema fora da VM na qual você executou o kill -3. Se você estiver redirecionando a saída do console da JVM para um arquivo, o dump do encadeamento estará nesse arquivo. Se a JVM estiver sendo executada em um console aberto, o dump do encadeamento será exibido em seu console.

Kris Babic
fonte
1
Existe uma maneira de redirecionar a saída de despejo de encadeamento JVM para um arquivo separado. Veja na minha resposta.
Vadzim
32

Há uma maneira de redirecionar a saída de despejo de thread da JVM no sinal de interrupção para separar o arquivo com a opção de diagnóstico LogVMOutput :

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log
Vadzim
fonte
5
Tecnicamente, isso não "redireciona" a saída de despejo de thread. Ele ativa o registro JVM no jvm.log (que inclui a saída de despejo de encadeamento), mas kill -QUIT ainda irá despejar no stdout do processo (também). Votado para a descrição de opções JVM obscuras :)
sqweek
25

Com o Java 8 em cena, jcmdé a abordagem preferida.

jcmd <PID> Thread.print

A seguir está o snippet da documentação da Oracle :

O lançamento do JDK 8 introduziu o Java Mission Control, o Java Flight Recorder e o utilitário jcmd para diagnosticar problemas com aplicativos JVM e Java. É sugerido usar o utilitário mais recente, jcmd em vez do utilitário jstack anterior para diagnósticos aprimorados e sobrecarga de desempenho reduzida.

No entanto, enviar isso com o aplicativo pode ser implicações de licenciamento que eu não tenho certeza.

Arnab Biswas
fonte
1
Infelizmente jcmdnão se conecta ao processo de serviço Windows com com.sun.tools.attach.AttachNotSupportedException: Insufficient memory or insufficient privileges to attachenquanto jstack -Fsucede: stackoverflow.com/questions/1197912/...
Vadzim
1
Você precisa executar jcmd <pid> Thread.dump com o mesmo usuário que o processo java, caso contrário, suas conexões serão interrompidas. Consulte stackoverflow.com/questions/25438983/…
Twilite de
11

No mesmo local onde o stdout da JVM está colocado. Se você tiver um servidor Tomcat, este será o catalina_(date).outarquivo.

Daniel
fonte
8

Ao usar kill -3, deve-se ver o despejo do thread na saída padrão. A maioria dos servidores de aplicativos grava a saída padrão em um arquivo separado. Você deve encontrá-lo lá ao usar kill -3. Existem várias maneiras de obter despejos de thread:

  • kill -3 <PID>: Dá saída para saída padrão.
  • Se alguém tiver acesso à janela do console onde o servidor está sendo executado, pode-se usar Ctrl+ Breakcombinação de teclas para gerar o rastreamento de pilha em STDOUT.
  • Para VMs de hotspot, também podemos usar o jstackcomando para gerar um despejo de thread. Faz parte do JDK. A sintaxe é a seguinte:

    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
fonte
Estou tendo problemas para usar Kill -3 <PID>. Funciona bem, mas também elimina o processo depois de gravar o despejo de thread no console. É suposto fazer isso?
Ashley
@Ashley - não kill -3 <PID>, não deve matar o JVM. Que tipo de aplicativo Java você está procurando?
slm
2

No Jboss você pode realizar o seguinte

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

Isso redirecionará sua saída / threadump para o console de arquivo especificado no comando acima.

anish
fonte
2
  1. Encontre o id do processo [PS ID]
  2. Execute jcmd [PS ID] Thread.print
Mehmet Erdemsoy
fonte
2

Etapas que você deve seguir se quiser o despejo de thread de seu processo Java autônomo

Etapa 1: obtenha o ID do processo para o script de shell que chama o programa 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

Etapa 2: Obtenha a ID do processo para o filho que foi invocado pelo runABCD. Use o PID acima para obter os filhos.

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

Etapa 3: obtenha o JSTACK para o processo específico. Obtenha a identificação do processo do seu processo XYSServer. ie 8536

linux$ jstack **8536** > threadDump.log
usuario
fonte