kill -3 pour obtenir un vidage de thread java

116

J'utilise la kill -3commande pour voir le vidage des threads de la JVM sous Unix. Mais où puis-je trouver la sortie de cette killcommande? Je suis perdu!!

Javanerd
la source
Quel processus tuez-vous? S'agit-il d'un serveur d'applications J2EE? Si c'est le cas, vous devriez trouver la trace de pile dans la sortie standard.
Luciano Fiandesio le
Je tue un processus qui exécute la classe java
javanerd
2
Ne devrait pas écrire le thread dump sur la console. puisque la classe java a la console comme sortie std
javanerd

Réponses:

194

Vous pouvez également utiliser jstack (inclus avec JDK) pour effectuer un vidage de thread et écrire la sortie où vous le souhaitez. N'est-ce pas disponible dans un environnement unix?

jstack PID > outfile
Joshua McKinnon
la source
1
Oui - au moment où il est exécuté. Vous pouvez également spécifier -l (L minuscule) pour une longue liste qui imprime des informations de verrouillage supplémentaires
Joshua McKinnon
2
Jusqu'à ce que la commande jstack échoue systématiquement en raison de "Impossible de déduire le type de thread de l'adresse" ;-(
noahlz
1
Si vous voyez cette erreur, je vous suggère de la contacter votre fournisseur. Une recherche rapide montre, par exemple, qu'il existe un bogue ouvert dans RHEL concernant cette erreur et openjdk ...
Joshua McKinnon
7
Il est à noter que jstack nécessite le JDK. Si vous exécutez des applications sur un serveur sur lequel seul le JRE est installé, vous devrez trouver un autre moyen de vidage de threads.
jeffkempf
1
Voici comment utiliser jstack pour obtenir le vidage de thread d'un processus s'exécutant sous un utilisateur différent, comme le service Windows: stackoverflow.com/questions/1197912/…
Vadzim
44

Le vidage de thread est écrit sur le système à partir de la machine virtuelle sur laquelle vous avez exécuté le fichier kill -3. Si vous redirigez la sortie de console de la JVM vers un fichier, le vidage de threads sera dans ce fichier. Si la JVM s'exécute dans une console ouverte, le vidage des threads sera affiché dans sa console.

Kris Babic
la source
1
Il existe un moyen de rediriger la sortie de vidage de thread JVM vers un fichier séparé. Voir dans ma réponse.
Vadzim
32

Il existe un moyen de rediriger la sortie de vidage de thread JVM sur le signal de rupture vers un fichier séparé avec l'option de diagnostic LogVMOutput :

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log
Vadzim
la source
5
Techniquement, cela ne «redirige» pas la sortie de vidage de thread. Il active la journalisation JVM dans jvm.log (qui inclut la sortie de vidage de thread) mais kill -QUIT sera toujours vider dans la sortie standard du processus (également). Voté pour la description des options JVM obscures :)
sqweek
25

Avec Java 8 en image, jcmdc'est l'approche préférée.

jcmd <PID> Thread.print

Voici l'extrait de la documentation Oracle :

La sortie de JDK 8 a introduit Java Mission Control, Java Flight Recorder et l'utilitaire jcmd pour diagnostiquer les problèmes avec les applications JVM et Java. Il est suggéré d'utiliser le dernier utilitaire, jcmd au lieu de l'utilitaire jstack précédent pour des diagnostics améliorés et une réduction des performances.

Cependant, l'expédition de ceci avec l'application peut avoir des implications de licence dont je ne suis pas sûr.

Arnab Biswas
la source
1
Malheureusement, jcmdne parvient pas à se connecter au processus de service Windows avec com.sun.tools.attach.AttachNotSupportedException: Insufficient memory or insufficient privileges to attachwhile jstack -Fréussit: stackoverflow.com/questions/1197912/…
Vadzim
1
Vous devez exécuter jcmd <pid> Thread.dump sous le même utilisateur que le processus java, sinon vos connexions seront abandonnées. Voir stackoverflow.com/questions/25438983/…
Twilite
11

Au même endroit où la sortie standard de la JVM est placée. Si vous avez un serveur Tomcat, ce sera le catalina_(date).outfichier.

Daniel
la source
8

Lorsque vous utilisez kill -3, vous devriez voir le vidage de thread dans la sortie standard. La plupart des serveurs d'applications écrivent la sortie standard dans un fichier séparé. Vous devriez le trouver là lorsque vous utilisez kill -3. Il existe plusieurs façons d'obtenir des threads:

  • kill -3 <PID>: Donne la sortie à la sortie standard.
  • Si l'on a accès à la fenêtre de la console où s'exécute le serveur, on peut utiliser Ctrl+ Breakcombinaison de clés pour générer la trace de pile sur STDOUT.
  • Pour les machines virtuelles hotspot, nous pouvons également utiliser la jstackcommande pour générer un vidage de thread. Cela fait partie du JDK. La syntaxe est la suivante:

    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
la source
J'ai du mal à utiliser Kill -3 <PID>. Cela fonctionne bien mais tue le processus également après avoir écrit le thread dump sur la console. Est-il censé faire ça?
Ashley
@Ashley - non ne kill -3 <PID>devrait pas tuer la JVM. Quel type d'application Java recherchez-vous?
slm
2

Dans Jboss, vous pouvez effectuer les opérations suivantes

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

Cela redirigera votre sortie / threadump vers la console de fichiers spécifiée dans la commande ci-dessus.

anish
la source
2
  1. Trouvez l'ID de processus [PS ID]
  2. Exécutez jcmd [PS ID] Thread.print
Mehmet Erdemsoy
la source
2

Étapes à suivre si vous souhaitez effectuer le vidage des threads de votre processus Java autonome

Étape 1: Obtenez l'ID de processus pour le script shell appelant le programme 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

Étape 2: Obtenez l'ID de processus pour l'enfant qui a été appelé par le runABCD. Utilisez le PID ci-dessus pour obtenir les enfants.

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

Étape 3: Obtenez le JSTACK pour le processus particulier. Obtenez l'ID de processus de votre processus XYSServer. soit 8536

linux$ jstack **8536** > threadDump.log
pseudo
la source