Een Java-threaddump vastleggen

1. Overzicht

In deze tutorial bespreken we verschillende manieren om de thread-dump van een Java-applicatie vast te leggen.

Een threaddump is een momentopname van de status van alle threads van een Java-proces. De status van elke thread wordt weergegeven met een stapeltracering, die de inhoud van de stapel van een thread laat zien. Een thread-dump is handig voor het diagnosticeren van problemen, omdat deze de activiteit van de thread weergeeft. Thread-dumps worden in platte tekst geschreven, dus we kunnen hun inhoud in een bestand opslaan en ze later in een teksteditor bekijken.

In de volgende secties zullen we meerdere tools en benaderingen doorlopen om een ​​thread-dump te genereren.

2. JDK-hulpprogramma's gebruiken

De JDK biedt verschillende hulpprogramma's die de threaddump van een Java-toepassing kunnen vastleggen. Alle hulpprogramma's bevinden zich onder het bak map in de JDK-homedirectory. Daarom kunnen we deze hulpprogramma's vanaf de opdrachtregel uitvoeren, zolang deze map zich in ons systeempad bevindt.

2.1. jstack

jstack is een JDK-hulpprogramma voor de opdrachtregel dat we kunnen gebruiken om een ​​thread-dump vast te leggen. Het duurt de pid van een proces en geeft de threaddump in de console weer. Als alternatief kunnen we de uitvoer naar een bestand omleiden.

Laten we eens kijken naar de basisopdrachtsyntaxis voor het vastleggen van een threaddump met jstack:

jstack [-F] [-l] [-m] 

Alle vlaggen zijn optioneel. Laten we eens kijken wat ze betekenen:

  • -F optie forceert een thread-dump; handig om te gebruiken wanneer jstack pid reageert niet (het proces is opgehangen)
  • -l optie instrueert het hulpprogramma om te zoeken naar eigen synchronizers in de heap en locks
  • -m optie drukt native stackframes (C & C ++) af naast de Java-stackframes

Laten we deze kennis gebruiken door een thread-dump vast te leggen en het resultaat om te leiden naar een bestand:

jstack 17264> /tmp/threaddump.txt

Onthoud dat we het pid van een Java-proces met behulp van de jps opdracht.

2.2. Java Mission Control

Java Mission Control (JMC) is een GUI-tool die gegevens van Java-applicaties verzamelt en analyseert. Nadat we JMC hebben gestart, wordt de lijst met Java-processen weergegeven die op een lokale computer worden uitgevoerd. We kunnen ook verbinding maken met externe Java-processen via JMC.

We kunnen met de rechtermuisknop op het proces klikken en klikken op de "Start de vluchtopname" keuze. Hierna is het Draden tabblad toont de Thread Dumps:

2.3. jvisualvm

jvisualvm is een tool met een grafische gebruikersinterface waarmee we Java-applicaties kunnen controleren, problemen oplossen en profileren. De GUI is eenvoudig maar zeer intuïtief en gemakkelijk te gebruiken.

Een van de vele opties stelt ons in staat om een ​​thread-dump vast te leggen. Als we met de rechtermuisknop op een Java-proces klikken en het "Thread Dump" optie, maakt de tool een thread-dump en opent deze op een nieuw tabblad:

Vanaf JDK 9 is Visual VM niet opgenomen in de Oracle JDK- en Open JDK-distributies. Daarom, als we Java 9 of nieuwere versies gebruiken, kunnen we de JVisualVM ophalen van de Visual VM open source projectsite.

2.4. jcmd

jcmd is een tool die werkt door opdrachtverzoeken naar de JVM te sturen. Hoewel krachtig, het bevat geen externe functionaliteit - we moeten het gebruiken op dezelfde machine waarop het Java-proces wordt uitgevoerd.

Een van de vele opdrachten is Thread.print. We kunnen het gebruiken om een ​​thread-dump te krijgen door de pid van het proces:

jcmd 17264 Thread.print

2.5. jconsole

Met jconsole kunnen we de stacktracering van elke thread inspecteren. Als we openen jconsole en maak verbinding met een actief Java-proces, we kunnen naar het Draden tab en zoek de stacktracering van elke thread:

2.6. Samenvatting

Het blijkt dus dat er veel manieren zijn om een ​​threaddump vast te leggen met behulp van JDK-hulpprogramma's. Laten we even stilstaan ​​bij elk en hun voor- en nadelen schetsen:

  • jstack: biedt de snelste en gemakkelijkste manier om een ​​thread-dump vast te leggen. Er zijn echter betere alternatieven beschikbaar vanaf Java 8
  • jmc: verbeterde JDK-profilering en diagnosetool. Het minimaliseert de prestatieoverhead die gewoonlijk een probleem is met profileringstools
  • jvisualvm: lichtgewicht en open-source profileringstool met een uitstekende GUI-console
  • jcmd: extreem krachtig en aanbevolen voor Java 8 en hoger. Een enkele tool die vele doelen dient - het vastleggen van thread-dump (jstack), heap dump (jmap), systeemeigenschappen en opdrachtregelargumenten (jinfo)
  • jconsole: laten we de trace-informatie van de threadstack inspecteren

3. Vanaf de opdrachtregel

Op bedrijfsapplicatieservers wordt om veiligheidsredenen alleen de JRE geïnstalleerd. We kunnen de bovengenoemde hulpprogramma's dus niet gebruiken omdat ze deel uitmaken van JDK. Er zijn echter verschillende opdrachtregelalternatieven waarmee we thread-dumps gemakkelijk kunnen vastleggen.

3.1. doden -3 Commando (Linux / Unix)

De eenvoudigste manier om een ​​thread-dump vast te leggen in Unix-achtige systemen is via het doden commando, dat we kunnen gebruiken om een ​​signaal naar een proces te sturen met behulp van de doden() systeemoproep. In dit geval sturen we het de -3 signaal.

Met onze zelfde pid Laten we uit eerdere voorbeelden eens kijken hoe u doden om een ​​thread-dump vast te leggen:

doden -3 17264

Op deze manier zal het signaalontvangende Java-proces de threaddump op de standaarduitvoer afdrukken.

Als we het Java-proces uitvoeren met de volgende combinatie van afstemmingsvlaggen, zal het ook de threaddump omleiden naar het gegeven bestand:

-XX: + UnlockDiagnosticVMOptions -XX: + LogVMOutput -XX: LogFile = ~ / jvm.log

Als we nu het -3 signaal, naast de standaarduitvoer, zal de dump beschikbaar zijn op ~ / jvm.log het dossier.

3.2. Ctrl + Break (Windows)

In Windows-besturingssystemen kunnen we een thread-dump vastleggen met behulp van de CTRL en Breken sleutel combinatie. Om een ​​threaddump te maken, navigeert u naar de console die wordt gebruikt om de Java-toepassing te starten en drukt u op CTRL en Breken sleutels samen.

Het is vermeldenswaard dat op sommige toetsenborden de Breken sleutel is niet beschikbaar. Daarom kan in dergelijke gevallen een thread-dump worden vastgelegd met CTRL, VERSCHUIVING, en Pauze sleutels samen.

Beide opdrachten drukken de threaddump naar de console af.

4. Programmatisch gebruiken ThreadMxBean

De laatste benadering die we in het artikel zullen bespreken, is het gebruik van JMX. We zullen gebruiken ThreadMxBean om de thread-dump vast te leggen. Laten we het in code bekijken:

privé statische String threadDump (boolean lockedMonitors, boolean lockedSynchronizers) {StringBuffer threadDump = nieuwe StringBuffer (System.lineSeparator ()); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean (); voor (ThreadInfo threadInfo: threadMXBean.dumpAllThreads (lockedMonitors, lockedSynchronizers)) {threadDump.append (threadInfo.toString ()); } return threadDump.toString (); }

In het bovenstaande programma voeren we verschillende stappen uit:

  1. In eerste instantie een leeg StringBuffer wordt geïnitialiseerd om de stapelinformatie van elke thread vast te houden.
  2. We gebruiken dan de ManagementFactory class om de instantie van op te halen ThreadMxBean. EEN ManagementFactory is een fabrieksklasse voor het verkrijgen van beheerde bonen voor het Java-platform. Bovendien een ThreadMxBean is de beheerinterface voor het threadsysteem van de JVM.
  3. Instelling vergrendeldMonitors en lockedSynchronizers waarden naar waar geeft aan dat de eigen synchronizers en alle vergrendelde monitoren in de thread-dump moeten worden vastgelegd.

5. Conclusie

In dit artikel hebben we meerdere manieren laten zien om een ​​threaddump vast te leggen.

Eerst bespraken we verschillende JDK-hulpprogramma's en vervolgens de opdrachtregelalternatieven. In de laatste sectie sloten we af met de programmatische aanpak met JMX.

Zoals altijd is de volledige broncode van het voorbeeld beschikbaar op GitHub.