Als Systemadministrator bin ich manchmal mit Situationen konfrontiert, in denen sich ein Programm abnormal verhält, während es überhaupt keine Fehler oder unsinnige Fehlermeldungen erzeugt.
In der Vergangenheit – bevor Java Einzug hielt – gab es zwei Gegenmaßnahmen:
- Wenn nichts anderes hilft – RTFM 😉
- Wenn selbst 1. nicht hilft – verfolgen Sie die Systemaufrufe und sehen Sie, was passiert
Normalerweise verwende ich strace -f
für diese Aufgabe mit Linux (andere Betriebssysteme haben ähnliche Trace-Tools). Während dies normalerweise für jedes altmodische Programm gut funktioniert, wird der Trace sehr unscharf, wenn man dasselbe auf einem Java macht -Prozess. Es gibt so viele Systemaufrufe, die scheinbar nichts mit einer wirklichen Aktion zu tun haben, dass es schrecklich ist, einen solchen Dump zu durchsuchen.
Gibt es bessere Möglichkeiten, dies zu tun (wenn der Quellcode nicht verfügbar ist)?
Akzeptierte Antwort:
Wie ckhan erwähnt hat, jstack
ist großartig, weil es den vollständigen Stack-Trace aller aktiven Threads in der JVM liefert. Dasselbe kann auf stderr der JVM mit SIGQUIT abgerufen werden.
Ein weiteres nützliches Tool ist jmap
die einen Heap-Dump vom JVM-Prozess mithilfe der PID des Prozesses abrufen kann:
jmap -dump:file=/tmp/heap.hprof $PID
Dieser Heap-Dump kann in Tools wie visualvm
geladen werden (das jetzt Teil der standardmäßigen Oracle-Java-SDK-Installation mit dem Namen jvisualvm ist). Darüber hinaus kann VisualVM eine Verbindung zur laufenden JVM herstellen und Informationen über die JVM anzeigen, einschließlich Diagrammen zur internen CPU-Nutzung, Thread-Anzahl und Heap-Nutzung – ideal zum Aufspüren von Lecks.
Ein weiteres Tool, jstat
, kann Garbage-Collection-Statistiken für die JVM über einen bestimmten Zeitraum sammeln, ähnlich wie vmstat, wenn es mit einem numerischen Argument ausgeführt wird (z. B. vmstat 3
).
Schließlich ist es möglich, einen Java-Agenten zu verwenden, um die Instrumentierung zur Ladezeit auf alle Methoden aller Objekte zu übertragen. Die Bibliothek javassist
kann dazu beitragen, dies sehr einfach zu machen. Es ist also möglich, Ihre eigene Ablaufverfolgung hinzuzufügen. Der schwierige Teil dabei wäre, einen Weg zu finden, Trace-Ausgaben nur dann zu erhalten, wenn Sie es wollten und nicht immer, was die JVM wahrscheinlich zu einem Crawl verlangsamen würde. Es gibt ein Programm namens dtrace
das funktioniert so ähnlich. Ich habe es versucht, war aber nicht sehr erfolgreich. Beachten Sie, dass Agenten nicht alle Klassen instrumentieren können, da diejenigen, die zum Bootstrap der JVM benötigt werden, geladen werden, bevor der Agent instrumentieren kann, und es dann zu spät ist, Instrumentierung zu diesen Klassen hinzuzufügen.
Mein Vorschlag – Beginnen Sie mit VisualVM und sehen Sie, ob Ihnen das sagt, was Sie wissen müssen, da es die aktuellen Threads und wichtige Statistiken für die JVM anzeigen kann.