töte -3, um einen Java-Thread-Dump zu erhalten

116

Ich verwende den kill -3Befehl, um den Thread-Dump der JVM unter Unix anzuzeigen. Aber wo finde ich die Ausgabe dieses killBefehls? Ich bin verloren!!

javanerd
quelle
Welchen Prozess tötest du? Ist es ein J2EE-App-Server? Wenn dies der Fall ist, sollten Sie den Stack-Trace im Standard finden.
Luciano Fiandesio
Ich töte einen Prozess, der die Java-Klasse
ausführt
2
Sollte das nicht den Thread-Dump auf die Konsole schreiben. da die Java-Klasse Konsole als
Standard

Antworten:

194

Alternativ können Sie jstack (im Lieferumfang von JDK enthalten) verwenden, um einen Thread-Dump zu erstellen und die Ausgabe zu schreiben, wo immer Sie möchten. Ist das in einer Unix-Umgebung nicht verfügbar?

jstack PID > outfile
Joshua McKinnon
quelle
1
Ja - zum Zeitpunkt der Ausführung. Sie können auch -l (Kleinbuchstabe L) für eine lange Liste angeben, die zusätzliche Sperrinformationen druckt
Joshua McKinnon
2
Bis der Befehl jstack aufgrund von "Thread-Typ kann nicht von Adresse abgeleitet werden" konsistent
fehlschlägt
1
Wenn Sie diesen Fehler sehen, empfehle ich, ihn bei Ihrem Lieferanten zu erfragen. Eine schnelle Suche zeigt zum Beispiel, dass es in RHEL einen offenen Fehler bezüglich dieses Fehlers und openjdk gibt ...
Joshua McKinnon
7
Es ist erwähnenswert, dass jstack das JDK benötigt. Wenn Sie Apps auf einem Server ausführen, auf dem nur die JRE installiert ist, müssen Sie ein anderes Mittel zum Thread-Dumping finden.
Jeffkempf
1
So verwenden Sie jstack, um den Thread-Dump eines Prozesses abzurufen, der unter verschiedenen Benutzern ausgeführt wird, z. B. Windows-Dienst: stackoverflow.com/questions/1197912/…
Vadzim
44

Der Thread-Dump wird von der VM, auf der Sie den ausgeführt haben, in das System geschrieben kill -3. Wenn Sie die Konsolenausgabe der JVM in eine Datei umleiten, befindet sich der Thread-Dump in dieser Datei. Wenn die JVM in einer offenen Konsole ausgeführt wird, wird der Thread-Dump in der Konsole angezeigt.

Kris Babic
quelle
1
Es gibt eine Möglichkeit, die JVM-Thread-Dump-Ausgabe in eine separate Datei umzuleiten. Siehe in meiner Antwort.
Vadzim
32

Es gibt eine Möglichkeit, die Ausgabe des JVM-Thread-Dumps beim Unterbrechungssignal in eine separate Datei mit der Diagnoseoption LogVMOutput umzuleiten :

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log
Vadzim
quelle
5
Technisch gesehen "leitet" dies die Thread-Dump-Ausgabe nicht um. Die JVM-Protokollierung in jvm.log (einschließlich Thread-Dump-Ausgabe) wird aktiviert, aber kill -QUIT wird weiterhin (auch) im Standard-Dump des Prozesses ausgegeben. Upvoted für die Beschreibung der obskuren JVM-Optionen :)
sqweek
25

Mit Java 8 im Bild jcmdist der bevorzugte Ansatz.

jcmd <PID> Thread.print

Es folgt der Ausschnitt aus der Oracle-Dokumentation :

Mit der Veröffentlichung von JDK 8 wurden Java Mission Control, Java Flight Recorder und das Dienstprogramm jcmd zur Diagnose von Problemen mit JVM- und Java-Anwendungen eingeführt. Es wird empfohlen, das neueste Dienstprogramm jcmd anstelle des vorherigen Dienstprogramms jstack zu verwenden, um die Diagnose zu verbessern und den Leistungsaufwand zu verringern.

Der Versand mit der Anwendung kann jedoch Auswirkungen auf die Lizenzierung haben, bei denen ich mir nicht sicher bin.

Arnab Biswas
quelle
1
Leider kann jcmdkeine Verbindung zum Windows-Dienst hergestellt werden, com.sun.tools.attach.AttachNotSupportedException: Insufficient memory or insufficient privileges to attachsolange dies jstack -Ferfolgreich ist: stackoverflow.com/questions/1197912/…
Vadzim
1
Sie müssen jcmd <pid> Thread.dump unter demselben Benutzer wie der Java-Prozess ausführen, andernfalls werden Ihre Verbindungen getrennt. Siehe stackoverflow.com/questions/25438983/…
Twilite
11

An derselben Stelle, an der sich das Standardout der JVM befindet. Wenn Sie einen Tomcat-Server haben, ist dies die catalina_(date).outDatei.

Daniel
quelle
8

Bei Verwendung von kill -3 sollte der Thread-Dump in der Standardausgabe angezeigt werden. Die meisten Anwendungsserver schreiben die Standardausgabe in eine separate Datei. Sie sollten es dort finden, wenn Sie kill -3 verwenden. Es gibt mehrere Möglichkeiten, Thread-Dumps abzurufen:

  • kill -3 <PID>: Gibt die Ausgabe an die Standardausgabe weiter.
  • Wenn man Zugriff auf das Konsolenfenster hat, in dem der Server ausgeführt wird, kann man Ctrl+ verwendenBreak Tastenkombination verwenden, um die Stapelverfolgung auf STDOUT zu generieren.
  • Für Hotspot-VMs können wir auch einen jstackBefehl verwenden, um einen Thread-Dump zu generieren. Es ist ein Teil des JDK. Die Syntax lautet wie folgt:

    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
quelle
Ich habe Probleme mit Kill -3 <PID>. Es funktioniert in Ordnung, beendet den Prozess jedoch auch nach dem Schreiben des Thread-Dumps in die Konsole. Soll es das tun?
Ashley
@Ashley - nein kill -3 <PID>sollte die JVM nicht töten. Welche Art von Java-App suchen Sie?
Slm
2

In Jboss können Sie Folgendes ausführen

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

Dadurch wird Ihre Ausgabe / Ihr Threadump an die im obigen Befehl angegebene Dateikonsole umgeleitet.

Anish
quelle
2
  1. Suchen Sie die Prozess-ID [PS ID]
  2. Führen Sie jcmd [PS ID] Thread.print aus
Mehmet Erdemsoy
quelle
2

Schritte, die Sie befolgen sollten, wenn Sie den Thread-Dump Ihres StandAlone Java-Prozesses möchten

Schritt 1: Rufen Sie die Prozess-ID für das Shell-Skript ab, das das Java-Programm aufruft

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

Schritt 2: Rufen Sie die Prozess-ID für das untergeordnete Element ab, das von runABCD aufgerufen wurde. Verwenden Sie die oben angegebene PID, um die Kinder zu erhalten.

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

Schritt 3: Holen Sie sich den JSTACK für den jeweiligen Prozess. Rufen Sie die Prozess-ID Ihres XYSServer-Prozesses ab. dh 8536

linux$ jstack **8536** > threadDump.log
Nick
quelle