Ich habe eine Java-Anwendung, die ich von einer Konsole aus ausführe, die wiederum einen anderen Java-Prozess ausführt. Ich möchte einen Thread / Heap-Dump dieses untergeordneten Prozesses erhalten.
Unter Unix könnte ich ein tun, kill -3 <pid>
aber unter Windows AFAIK ist Strg-Break in der Konsole die einzige Möglichkeit, einen Thread-Dump zu erhalten. Aber das gibt mir nur den Speicherauszug des übergeordneten Prozesses, nicht des Kindes.
Gibt es einen anderen Weg, um diesen Heap-Dump zu bekommen?
java
jvm
heap-dump
thread-dump
Kasun Siyambalapitiya
quelle
quelle
Antworten:
Sie können verwenden
jmap
, um einen Speicherauszug aller laufenden Prozesse zu erstellen, vorausgesetzt, Sie kennen diepid
.Verwenden Sie den Task-Manager oder den Ressourcenmonitor, um die zu erhalten
pid
. Dannum den Haufen für diesen Prozess zu bekommen.
quelle
Sie verwechseln zwei verschiedene Java-Dumps.
kill -3
generiert einen Thread-Dump, keinen Heap-Dump.Um unter Windows einen Thread-Dump zu erstellen, ist CTRL+ BREAKder einfachste Weg , wenn Ihre JVM im Vordergrund steht. Wenn Sie unter Windows eine Unix-ähnliche Shell wie Cygwin oder MobaXterm haben, können Sie diese
kill -3 {pid}
wie unter Unix verwenden.Um einen Thread-Dump unter Unix durchzuführen, CTRL+ Cwenn Ihre JVM im Vordergrund steht oder
kill -3 {pid}
funktioniert, solange Sie die richtige PID für die JVM erhalten.Auf beiden Plattformen enthält Java mehrere Dienstprogramme, die helfen können. Für Thread-Dumps
jstack {pid}
ist dies die beste Wahl. http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.htmlNur um die Dump-Frage zu beenden: Heap-Dumps werden nicht häufig verwendet, da sie schwer zu interpretieren sind. Sie enthalten jedoch viele nützliche Informationen, wenn Sie wissen, wo und wie Sie sie betrachten müssen. Die häufigste Verwendung ist das Auffinden von Speicherlecks. Es wird
-D
empfohlen, den Befehl in der Java-Befehlszeile so festzulegen, dass der Heap-Dump bei einem OutOfMemoryError automatisch generiert-XX:+HeapDumpOnOutOfMemoryError
wird. Sie können jedoch auch manuell einen Heap-Dump auslösen. Am häufigsten wird das Java-Dienstprogramm verwendetjmap
.HINWEIS: Dieses Dienstprogramm ist nicht auf allen Plattformen verfügbar. Ab JDK 1.6
jmap
ist unter Windows verfügbar.Eine beispielhafte Befehlszeile würde ungefähr so aussehen
Die Ausgabe "myheap.bin" ist (für die meisten von uns) nicht lesbar, und Sie benötigen ein Tool, um sie zu analysieren. Ich bevorzuge MAT. http://www.eclipse.org/mat/
quelle
Ich denke, der beste Weg, um eine .hprof-Datei im Linux-Prozess zu erstellen, ist mit dem Befehl jmap . Beispielsweise:
jmap -dump:format=b,file=filename.hprof {PID}
quelle
Zusätzlich zur Verwendung der erwähnten jconsole / visualvm können Sie diese
jstack -l <vm-id>
in einem anderen Befehlszeilenfenster verwenden und diese Ausgabe erfassen.Die <vm-id> kann mithilfe des Task-Managers (dies ist die Prozess-ID unter Windows und Unix) oder mithilfe von gefunden werden
jps
.Beide
jstack
undjps
sind in Sun JDK Version 6 und höher enthalten.quelle
Ich empfehle Java VisualVM, das mit dem JDK (jvisualvm.exe) verteilt wird. Es kann sich dynamisch verbinden und auf die Threads und den Heap zugreifen. Ich habe für einige Probleme von unschätzbarem Wert gefunden.
quelle
Wenn Sie sich auf Server-JRE 8 und höher befinden, können Sie Folgendes verwenden:
quelle
Probieren Sie eine der folgenden Optionen aus.
Für 32-Bit-JVM:
Für 64-Bit-JVM (explizit zitiert):
Für 64-Bit-JVM mit G1GC-Algorithmus in VM-Parametern (mit dem G1GC-Algorithmus wird nur der Heap für lebende Objekte generiert):
Verwandte SE-Frage: Java-Heap-Dump-Fehler mit jmap-Befehl: Vorzeitiger EOF
Schauen Sie sich
jmap
in diesem Artikel verschiedene Optionen anquelle
Wenn Sie einen Heapdump mit nicht genügend Arbeitsspeicher wünschen, können Sie Java mit der Option starten
-XX:-HeapDumpOnOutOfMemoryError
cf JVM - Optionen Referenzseite
quelle
Sie können ausführen
jconsole
(im Java 6 SDK enthalten) und dann eine Verbindung zu Ihrer Java-Anwendung herstellen. Es zeigt Ihnen jeden laufenden Thread und seine Stapelverfolgung.quelle
Sie können die
kill -3 <pid>
von Cygwin senden . Sie müssen die Cygwin-ps
Optionen verwenden, um Windows-Prozesse zu finden, und dann einfach das Signal an diesen Prozess senden.quelle
Sie müssen die Ausgabe der zweiten ausführbaren Java-Datei in eine Datei umleiten. Verwenden Sie dann SendSignal , um "-3" an Ihren zweiten Prozess zu senden .
quelle
Wenn Sie JDK 1.6 oder höher verwenden, können Sie mit dem
jmap
Befehl einen Heap-Dump eines Java-Prozesses erstellen. Voraussetzung ist, dass Sie die ProcessID kennen.Wenn Sie sich auf einem Windows-Computer befinden, können Sie den Task-Manager verwenden, um die PID abzurufen. Für Linux-Computer können Sie verschiedene Befehle wie
ps -A | grep java
odernetstat -tupln | grep java
oder verwendentop | grep java
, hängen von Ihrer Anwendung.Dann können Sie den Befehl wie
jmap -dump:format=b,file=sample_heap_dump.hprof 1234
1234 PID verwenden.Zur Interpretation der hprof-Datei stehen verschiedene Tools zur Verfügung . Ich werde das Visualvm-Tool von Oracle empfehlen, das einfach zu bedienen ist.
quelle
Wenn Sie die Konsole / das Terminal aus irgendeinem Grund nicht verwenden können (oder wollen), gibt es eine alternative Lösung. Sie können die Java-Anwendung veranlassen, den Thread-Dump für Sie zu drucken. Der Code, der die Stapelverfolgung sammelt, ist relativ einfach und kann an eine Schaltfläche oder eine Weboberfläche angehängt werden.
Diese Methode gibt eine Zeichenfolge zurück, die folgendermaßen aussieht:
Für diejenigen, die an einer Java 8-Version mit Streams interessiert sind, ist der Code noch kompakter:
Sie können diesen Code einfach testen mit:
quelle
Das folgende Skript verwendet PsExec, um eine Verbindung zu einer anderen Windows-Sitzung herzustellen, sodass es auch bei Verbindung über den Remotedesktopdienst funktioniert.
Ich habe ein kleines Batch-Skript für Java 8 (mit
PsExec
undjcmd
) mit dem Namen geschriebenjvmdump.bat
, das die Threads, den Heap, die Systemeigenschaften und die JVM-Argumente ausgibt.Es muss in derselben Windows-Sitzung des Benutzers ausgeführt werden, der die JVM gestartet hat. Wenn Sie also eine Verbindung über Remotedesktop herstellen, müssen Sie möglicherweise eine Eingabeaufforderung starten
Session 0
und von dort aus ausführen. z.BDadurch werden Sie (klicken Sie auf das Taskleistensymbol unten) zur
View the message
interaktiven Sitzung aufgefordert , die Sie zur neuen Konsole in der anderen Sitzung führt, von der aus Sie dasjvmdump.bat
Skript ausführen können .quelle
Wie erhalte ich die Prozess-ID der Java-Anwendung?
Führen Sie den Befehl 'jcmd' aus, um die Prozess-ID von Java-Anwendungen abzurufen.
Wie bekomme ich Thread Dump?
jcmd PID Thread.print> thread.dump
Referenz - Link
Sie können sogar jstack verwenden, um einen Thread-Dump abzurufen (jstack PID> thread.dump). Referenz - Link
Wie bekomme ich Heap Dump?
Verwenden Sie das jmap-Tool, um den Heap-Dump abzurufen. jmap -F -dump: live, format = b, file = heap.bin PID
PID steht für die Prozess-ID der Anwendung. Referenz - Link
quelle
Vielleicht jcmd ?
Das Dienstprogramm Jcmd wird zum Senden von Diagnosebefehlsanforderungen an die JVM verwendet. Diese Anforderungen sind nützlich, um Java- Flugaufzeichnungen zu steuern, Fehler zu beheben und JVM- und Java-Anwendungen zu diagnostizieren.
Das jcmd-Tool wurde mit Oracle 7 von Oracle eingeführt und ist besonders nützlich bei der Fehlerbehebung bei Problemen mit JVM-Anwendungen, indem es die IDs von Java-Prozessen (ähnlich wie jps) identifiziert, Heap-Dumps (ähnlich wie jmap) und Thread-Dumps (ähnlich wie jstack) abruft ), Anzeigen von Merkmalen virtueller Maschinen wie Systemeigenschaften und Befehlszeilenflags (ähnlich wie jinfo) und Abrufen von Garbage Collection-Statistiken (ähnlich wie jstat). Das jcmd-Tool wurde als "Schweizer Taschenmesser zur Untersuchung und Lösung von Problemen mit Ihrer JVM-Anwendung" und als "verstecktes Juwel" bezeichnet.
Hier ist der Prozess, den Sie zum Aufrufen von
jcmd
: verwenden müssen:jcmd <pid> GC.heap_dump <file-path>
Weitere Informationen zur Verwendung des Java-Heap-Dumps finden Sie hier .
quelle
Visualvm Follow-up:
Wenn Sie von jvisualvm aus keine Verbindung zu Ihrer laufenden JVM herstellen können, weil Sie sie nicht mit den richtigen JVM-Argumenten gestartet haben (und sie sich auf der Remote-Box befindet), führen Sie sie
jstatd
auf der Remote-Box aus. Fügen Sie dann unter der Annahme hinzu, dass Sie eine direkte Verbindung haben Doppelklicken Sie als "Remote-Host" in visualvm auf den Hostnamen, und alle anderen JVMs in diesem Feld werden auf magische Weise in visualvm angezeigt.Wenn Sie keine "direkte Verbindung" zu den Ports dieser Box haben, können Sie dies auch über einen Proxy tun .
Sobald Sie den gewünschten Prozess sehen können, führen Sie einen Drilldown in jvisualvm durch und verwenden Sie die Registerkarte Monitor -> Schaltfläche "Heapdump".
quelle
Der folgende Java-Code wird verwendet, um den Heap-Dump eines Java-Prozesses durch Angabe der PID abzurufen. Das Programm verwendet eine Remote-JMX-Verbindung, um den Heap zu sichern. Es kann für jemanden hilfreich sein.
}}
quelle
Um einen Thread-Dump / Heap-Dump von einem untergeordneten Java-Prozess in Windows zu übernehmen, müssen Sie als ersten Schritt die untergeordnete Prozess-ID identifizieren.
Durch Ausgabe des Befehls: jps können Sie alle Java-Prozess- IDs abrufen , die auf Ihrem Windows-Computer ausgeführt werden. Aus dieser Liste müssen Sie die untergeordnete Prozess-ID auswählen. Sobald Sie eine untergeordnete Prozess-ID haben, gibt es verschiedene Optionen zum Erfassen von Thread-Dumps und Heap-Dumps.
Erfassen von Thread-Dumps:
Es gibt 8 Optionen zum Erfassen von Thread-Dumps:
Details zu jeder Option finden Sie in diesem Artikel . Sobald Sie Thread-Dumps erfasst haben, können Sie Tools wie fastThread und Samuraito verwenden, um Thread-Dumps zu analysieren.
Erfassen von Heap-Dumps:
Es gibt 7 Optionen zum Erfassen von Heap-Dumps:
jmap
-XX: + HeapDumpOnOutOfMemoryError
jcmd
JVisualVM
JMX
Programmatischer Ansatz
Verwaltungskonsolen
Details zu jeder Option finden Sie in diesem Artikel . Sobald Sie Heapdump erfasst haben, können Sie Tools wie verwenden Eclipse - Memory - Analyse - Tool , HeapHero auf die erfassten Heapspeicherauszüge zu analysieren.
quelle
In einem Oracle JDK haben wir einen Befehl namens jmap (verfügbar im bin-Ordner von Java Home). Die Verwendung des Befehls erfolgt wie folgt
Beispiel: jmap -dump: live, format = b, file = heap.bin (pid)
quelle