Wie analysieren Java-Thread-Dumps - DZone Leistung

Der Inhalt dieses Artikels wurde ursprünglich von Tae Jin Gu auf dem CUBRID Blog geschrieben.

Java und Faden

Ein Web-Server verwendet Dutzende bis Hunderte von Threads eine große Anzahl gleichzeitiger Benutzer zu verarbeiten. Wenn zwei oder mehrere Threads die gleichen Ressourcen, ein Streit zwischen den Fäden verwenden ist unvermeidlich, und manchmal Deadlock auftritt.







Thread Anstoß ist ein Status, in dem ein Faden auf eine Sperre wartet, von einem anderen Thread gehalten wird, angehoben werden. Verschiedene Threads Zugriff häufig gemeinsam genutzte Ressourcen auf einer Web-Anwendung. Zum Beispiel ein Protokoll aufzunehmen, den Thread versucht, das Protokoll aufnehmen muss eine Sperre erhalten und die freigegebenen Ressourcen zugreifen.

Deadlock ist eine spezielle Art von Faden Anstoß, in denen zwei oder mehr Threads für die anderen Threads warten, ihre Aufgaben zu vervollständigen, um ihre eigenen Aufgaben zu erledigen.

Verschiedene Probleme können von Thread-Konkurrenz entstehen. Um solche Probleme zu analysieren, müssen Sie das Thread-Dump verwenden. Ein Thread-Dump wird Ihnen die Informationen über den genauen Status jedes Threads.

Hintergrundinformationen für Java Threads

Themen-Synchronisation

Ein Thread kann mit anderen Threads zur selben Zeit verarbeitet werden. Um Kompatibilität zu gewährleisten, wenn mehrere Threads gemeinsam genutzte Ressourcen zu verwenden versuchen, soll ein Thread zu einem Zeitpunkt unter Verwendung von Thread-Synchronisierung der freigegebenen Ressourcen zugreifen darf.

Thread-Synchronisierung auf Java kann mit Monitor erfolgen. Jedes Java-Objekt hat einen einzigen Monitor. Der Monitor kann nur ein Thread gehört. Für einen Thread einen Monitor zu besitzen, die von einem anderen Thread gehört, muss es in der Warteschlange warten, bis der andere Thread seinen Monitor freigibt.

Thread-Status

Um ein Thread-Dump zu analysieren, müssen Sie den Status der Threads kennen. Die Zustände der Threads auf java.lang.Thread.State angegeben.

Abbildung 1: Thread-Status.

Gewindearten

Java-Threads können in zwei Teile geteilt werden:

  1. Daemon-Threads;
  2. und nicht-Daemon-Threads.

Daemon-Threads aufhören zu arbeiten, wenn es keine anderen nicht-Daemon-Threads sind. Auch wenn Sie standardmäßig keine Threads erstellen, wird die Java-Anwendung mehrere Threads erstellen. Die meisten von ihnen sind Daemon-Threads, vor allem für die Verarbeitung von Aufgaben, wie beispielsweise Speicherbereinigungs oder JMX.

Ein Thread die "static void main (String [] args)‘ Methode ausgeführt wird, als nicht-Daemon-Thread erstellt wurde, und, wenn dieser Faden nicht mehr funktioniert, werden alle anderen Threads Daemon wird auch stoppen. (Das Gewinde dieser Hauptverfahren ausgeführt wird der VM-Thread in HotSpot VM bezeichnet.)

Wie Sie einen Thread-Dump

Wir werden die drei am häufigsten verwendeten Methoden einzuführen. Beachten Sie, dass es viele andere Möglichkeiten gibt, ein Thread-Dump zu erhalten. Ein Thread kann Dump zeigen nur den Faden Status zum Zeitpunkt der Messung, um so die Änderung in der Thread-Status, um zu sehen, ist es empfehlenswert, sie von 5 bis 10 mal mit 5-Sekunden-Intervallen zu extrahieren.

Wie Sie ein Thread-Dump Mit jstack

In JDK 1.6 und höher, ist es möglich, ein Thread-Dump auf MS Windows erhalten mit jstack.

Verwenden Sie PID über JPS die PID des aktuell laufenden Java-Anwendung Prozess zu überprüfen.

Verwenden der extrahierten PID als Parameter des jstack ein Thread-Dump zu erhalten.

Ein Thread-Dump Mit jvisualvm

Generieren Sie einen Thread-Dump durch ein Programm wie jvisualvm verwenden.

Abbildung 2: Ein Thread-Dump Mit VisualVM.

Die Aufgabe auf der linken Seite zeigt die Liste der laufenden Prozesse. Klicken Sie auf den Prozess, für die Sie die Informationen möchten, und wählen Sie den Faden Registerkarte den Faden Informationen in Echtzeit zu überprüfen. Klicken Sie auf die Thread-Dump-Taste auf der oberen rechten Ecke der Thread-Dump-Datei zu erhalten.

Die Erzeugung in einem Linux Terminal

Erhalten Sie den Prozess pid von ps -ef die pid des aktuell laufenden Java-Prozess überprüfen Befehl.

Verwenden des extrahierten pid als Parameter Abtötungs -SIGQUIT (3) ein Thread-Dump zu erhalten.

Thread Informationen vom Thread-Dump-Datei

  • Thread-Namen. Wenn java.lang.Thread Klasse unter Verwendung eines Thread zu erzeugen, wird der Faden Gewinde- (Number) genannt, wohingegen, wenn java.util.concurrent.ThreadFactory Klasse verwenden, wird es pool- (Nummer) genannt werden -thread- (Anzahl ).
  • Priorität. Repräsentiert die Priorität der Threads.
  • Thread-ID. Stellt die eindeutige ID für die Fäden. (Einige nützliche Informationen, einschließlich der CPU- oder Speichernutzung des Gewindes, kann durch die Verwendung Thread-ID erhalten werden.)
  • Thread-Status. Stellt den Zustand der Threads.
  • Thread Aufrufliste. Repräsentiert die Aufrufliste Informationen der Fäden.






Thread Dump Patterns nach Typ

Wenn konnte keine Sperre erhalten (GESPERRT)

Dies ist, wenn die Gesamtleistung der Anwendung verlangsamt, da ein Thread die Sperre besetzt hält und verhindert, dass andere Threads von ihm zu erhalten. In dem folgenden Beispiel läuft BLOCKED_TEST pool-1-thread-1 Gewinde mit < 0x0000000780a000b0 > sperren, während BLOCKED_TEST pool-1-thread-2 und BLOCKED_TEST pool-1-thread-3 Threads warten zu erhalten < 0x0000000780a000b0 > sperren.

Abbildung 3: Ein Thread andere Threads blockiert.

Wenn in Deadlock-Status

Dies ist, wenn Thread A braucht Thread B zu erhalten, ist seine Verriegelung Aufgabe fortzusetzen, während Thread B braucht Thread A zu erhalten, ist Sperre seine Aufgabe fortzusetzen. siehe in dem Thread-Dump, können Sie die DEADLOCK_TEST-1 Gewinde hat 0x00000007d58f5e48 Sperre, und versucht 0x00000007d58f5e60 Sperre zu erhalten. Sie können auch sehen, dass DEADLOCK_TEST-2 Gewinde 0x00000007d58f5e60 Sperre hat, und versucht 0x00000007d58f5e78 Sperre zu erhalten. Auch DEADLOCK_TEST-3 Gewinde hat 0x00000007d58f5e78 Sperre, und versucht 0x00000007d58f5e48 Sperre zu erhalten. Wie Sie sehen können, ist jeder Thread wartet ein anderer Thread die Sperre zu erhalten, und dieser Zustand wird sich nicht ändern, bis ein Thread seine Sperre verwirft.

Abbildung 4: Threads in einem Deadlock-Zustand.

Wenn Kontinuierlich Warten Nachrichten von einem Remote-Server Receive

Der Faden scheint normal zu sein, da sein Zustand beibehält als RUNNABLE zeigt. Wenn Sie jedoch die Thread-Dumps zeitlich ausrichten, können Sie sehen, dass socketReadThread Faden unendlich wartet die Fassung zu lesen.

Abbildung 5: Kontinuierliche Wartestatus.

wenn Waiting

Der Faden wird beibehalten WAIT-Status. Im Thread-Dump, hält IoWaitThread Thread wartet eine Nachricht von LinkedBlockingQueue zu erhalten. Wenn es keine Nachricht zu sein für LinkedBlockingQueue fortsetzt, dann wird der Thread-Status nicht ändern.

Abbildung 6: Wartestatus.

Wenn Gewinde Ressourcen nicht normal organisiert werden

Unnötige Threads häufen sich, wenn Thread Ressourcen normalerweise nicht organisiert werden können. Wenn dies der Fall ist, ist es empfehlenswert, den Thread Organisationsprozess oder überprüfen Sie die Bedingungen für Threadbeendigung zu überwachen.

Abbildung 7: Unorganized Threads.

Wie zu lösen Probleme durch Thread-Dump verwenden

Beispiel 1: Wenn die CPU-Auslastung ist ungewöhnlich hoch

1. Extrahieren der Thread, der die höchste CPU-Auslastung hat.

Von der Anwendung erfahren Sie, welcher Thread die die CPU verwendet wird.

2. Nachdem Sie den Thread-Dump des Erwerb, die Klage des Thread überprüfen.

Extrahieren Sie den Thread-Dump einer Anwendung mit einem PID von 10029, dann finden Sie den Faden mit einem nid von 0x2737.

Extrakt Thread-Dumps mehrmals stündlich, und überprüfen die Statusänderung der Fäden um das Problem zu bestimmen.

Beispiel 2: Wenn die Verarbeitungsleistung ist abnorm langsame

Thread-Dumps mehrmals, finden Sie die Liste der Themen mit blockiertem Zustand nach dem Erwerb.

Erwerben Sie die Liste von Threads mit blockiertem Zustand nach Erhalt der Faden mehrmals Dumps.

Wenn die Fäden blockiert sind, extrahiert die Fäden an das Schloss zusammen, dass die Fäden zu erhalten versuchen.

Durch die Thread-Dump können Sie bestätigen, dass der Thread-Status, weil GESPERRT bleibt < 0xe0375410 > Sperre kann nicht erhalten werden. Dieses Problem kann durch die Analyse Stapelüberwachung aus dem Gewinde gelöst wird derzeit die Sperre hält.

Es gibt zwei Gründe, warum häufig das obige Muster unter Verwendung von DBMS in Anwendungen angezeigt. Der erste Grund ist unzureichend Konfigurationen. Trotz der Tatsache, dass die Fäden noch arbeiten, können sie nicht ihre beste Leistung zeigen, da die Konfigurationen für DBCP und dergleichen nicht ausreichend sind. Wenn Sie Thread-Dumps mehrere Male extrahieren und vergleichen sie, werden Sie oft sehen, dass einige der Themen, die zuvor in einem anderen Zustand blockiert wurden.

Der zweite Grund ist die abnorme Verbindung. Wenn die Verbindung mit DBMS abnormal bleibt, warten die Fäden, bis die Zeit aus ist. In diesem Fall, auch nach dem Faden Extrahieren Dumps mehrmals und vergleichen sie, werden Sie sehen, dass die zu DBMS verwandten Themen sind nach wie vor in einem blockierten Zustand. Durch geeignete Wahl der Werte, wie der Timeout-Wert zu ändern, können Sie die Zeit, in der Verkürzung das Problem auftritt.

Coding für Easy Thread-Dump

Naming Themen

Wenn ein Thread erstellt wird java.lang.Thread Objekt, wird der Thread namens Gewinde- (Number). Wenn ein Thread erstellt wird java.util.concurrent.DefaultThreadFactory Objekt verwendet, wird der Thread namens pool- (Number) -thread- (Number). Wenn zehn bis Tausende von Threads für eine Anwendung zu analysieren, wenn alle noch die Fäden ihre Standardnamen haben, sie zu analysieren wird sehr schwierig, weil es schwierig ist, die Fäden zu unterscheiden analysiert werden.

Daher werden Sie die Gewohnheit der Namensgebung, die Fäden zu entwickeln empfohlen, wenn ein neuer Thread erstellt wird.

Wenn Sie einen Thread erstellen mit java.lang.Thread. Sie können mithilfe der Schöpfer Parameter der Thread einen eigenen Namen geben.

Wenn Sie einen Thread erstellen mit java.util.concurrent.ThreadFactory. Sie können es nennen, indem Sie Ihre eigenen Thread zu erzeugen. Wenn Sie keine spezielle Funktionalitäten benötigen, dann können Sie MyThreadFactory verwenden, wie unten beschrieben:

Beziehen Ausführlichere Informationen von MBean Verwenden

Sie können Thread Objekte mit MBean erhalten. Sie können auch weitere Informationen erhalten, die schwierig sein würde, über Thread-Dumps zu erwerben, durch Thread verwenden.

Sie können die Höhe der Zeit erwerben, die die Fäden gewartet oder wurden unter Verwendung des Verfahrens in Thread GESPERRT, und durch diese verwenden Sie können auch die Liste der Themen erhalten, die für einen ungewöhnlich langen Zeitraum inaktiv war.

Abschließend







In Verbindung stehende Artikel