Optagelse af en Java-tråddump

1. Oversigt

I denne vejledning diskuterer vi forskellige måder at fange tråddumpen af ​​en Java-applikation.

En tråddump er et øjebliksbillede af tilstanden for alle tråde i en Java-proces. Tilstanden for hver tråd præsenteres med et stakspor, der viser indholdet af en tråds stak. En tråddump er nyttig til diagnosticering af problemer, da den viser trådens aktivitet. Tråddumps er skrevet i almindelig tekst, så vi kan gemme deres indhold i en fil og se på dem senere i en teksteditor.

I de næste sektioner gennemgår vi flere værktøjer og tilgange til at generere en tråddump.

2. Brug af JDK Utilities

JDK tilbyder flere værktøjer, der kan fange tråddumpen i en Java-applikation. Alle hjælpeprogrammer er placeret under beholder mappe inde i JDK-hjemmekataloget. Derfor kan vi udføre disse hjælpeprogrammer fra kommandolinjen, så længe denne mappe er i vores systemsti.

2.1. jstack

jstack er et kommandolinj JDK-værktøj, vi kan bruge til at fange en tråddump. Det tager pid af en proces og viser tråddumpen i konsollen. Alternativt kan vi omdirigere dets output til en fil.

Lad os se på den grundlæggende kommandosyntaks til at fange en tråddump ved hjælp af jstack:

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

Alle flag er valgfri. Lad os se, hvad de mener:

  • -F option tvinger en tråddumpning; praktisk at bruge når jstack pid svarer ikke (processen er hængt)
  • -l option instruerer hjælpeprogrammet til at lede efter synkroniserbare enheder i bunken og låse
  • -m mulighed udskriver native stack frames (C & C ++) ud over Java stack frames

Lad os bruge denne viden ved at fange en thread dump og omdirigere resultatet til en fil:

jstack 17264> /tmp/threaddump.txt

Husk, at vi nemt kan få pid af en Java-proces ved hjælp af jps kommando.

2.2. Java Mission Control

Java Mission Control (JMC) er et GUI-værktøj, der indsamler og analyserer data fra Java-applikationer. Når vi har startet JMC, viser den listen over Java-processer, der kører på en lokal maskine. Vi kan også oprette forbindelse til eksterne Java-processer via JMC.

Vi kan højreklikke på processen og klikke på “Start flyoptagelse" mulighed. Efter dette, Tråde fanen viser tråddumps:

2.3. jvisualvm

jvisualvm er et værktøj med en grafisk brugergrænseflade, der lader os overvåge, fejlfinde og profilere Java-applikationer. GUI'en er enkel, men meget intuitiv og nem at bruge.

En af dens mange muligheder giver os mulighed for at fange en tråddump. Hvis vi højreklikker på en Java-proces og vælger “Tråddump” mulighed, værktøjet opretter en tråddump og åbner den i en ny fane:

Fra og med JDK 9 er Visual VM ikke inkluderet i Oracle JDK og Open JDK distributioner. Derfor, hvis vi bruger Java 9 eller nyere versioner, kan vi hente JVisualVM fra Visual VM open source-projektwebstedet.

2.4. jcmd

jcmd er et værktøj, der fungerer ved at sende kommandoanmodninger til JVM. Selvom det er stærkt, er det indeholder ikke nogen fjernfunktionalitet - vi er nødt til at bruge det på den samme maskine, hvor Java-processen kører.

En af dens mange kommandoer er Tråd.print. Vi kan bruge det til at få en tråddump bare ved at specificere pid af processen:

jcmd 17264 Trådtryk

2.5. jconsole

jconsole lader os inspicere stakssporingen for hver tråd. Hvis vi åbner jconsole og oprette forbindelse til en kørende Java-proces, vi kan navigere til Tråde fanen og find hver tråds stakspor:

2.6. Resumé

Så som det viser sig, er der mange måder at fange en thread dump ved hjælp af JDK-værktøjer. Lad os tage et øjeblik til at reflektere over hver og skitsere deres fordele og ulemper:

  • jstack: giver den hurtigste og nemmeste måde at fange en tråddump på. Der findes dog bedre alternativer startende med Java 8
  • jmc: forbedret JDK-profilering og diagnosticeringsværktøj. Det minimerer performance overhead, der normalt er et problem med profileringsværktøjer
  • jvisualvm: Let og open source-profilværktøj med en fremragende GUI-konsol
  • jcmd: ekstremt kraftfuld og anbefales til Java 8 og nyere. Et enkelt værktøj, der tjener mange formål - at fange tråddump (jstack), bunke dump (jmap), systemegenskaber og kommandolinjeargumenter (jinfo)
  • jconsole: lad os inspicere sporingsinformation om trådstak

3. Fra kommandolinjen

I enterprise-applikationsservere er kun JRE installeret af sikkerhedsmæssige årsager. Således kan vi ikke bruge de ovennævnte hjælpeprogrammer, da de er en del af JDK. Der er dog forskellige kommandolinjealternativer, der giver os mulighed for nemt at fange tråddumps.

3.1. dræbe -3 Kommando (Linux / Unix)

Den nemmeste måde at fange en tråddump på Unix-lignende systemer er gennem dræbe kommando, som vi kan bruge til at sende et signal til en proces ved hjælp af dræbe() systemopkald. I dette brugssag sender vi det -3 signal.

Brug vores samme pid fra tidligere eksempler, lad os se på, hvordan man bruger dræbe at fange en tråddump:

dræb -3 17264

På denne måde udskriver den signalmodtagende Java-proces tråddumpen på standardoutputtet.

Hvis vi kører Java-processen med følgende kombination af tuning af flag, omdirigerer den også tråddumpen til den givne fil:

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

Nu hvis vi sender -3 ud over standardoutputtet vil dumpen være tilgængelig på ~ / jvm.log fil.

3.2. Ctrl + Break (Windows)

I Windows-operativsystemer kan vi fange en tråddump ved hjælp af CTRL og Pause tastekombination. For at tage en tråddump skal du navigere til den konsol, der blev brugt til at starte Java-applikationen og trykke på CTRL og Pause tasterne sammen.

Det er værd at bemærke, at det på nogle tastaturer er Pause nøgle er ikke tilgængelig. Derfor kan der i sådanne tilfælde fanges en tråddump ved hjælp af CTRL, FLYTTEog Pause tasterne sammen.

Begge disse kommandoer udskriver tråddumpen til konsollen.

4. Programmatisk brug TrådMxBønne

Den sidste tilgang, vi vil diskutere i artiklen, bruger JMX. Vi bruger TrådMxBønne for at fange tråddumpen. Lad os se det i kode:

privat statisk String threadDump (boolean lockedMonitors, boolean lockedSynchronizers) {StringBuffer threadDump = new StringBuffer (System.lineSeparator ()); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean (); for (ThreadInfo threadInfo: threadMXBean.dumpAllThreads (lockedMonitors, lockedSynchronizers)) {threadDump.append (threadInfo.toString ()); } returner threadDump.toString (); }

I ovenstående program udfører vi flere trin:

  1. Først en tom StringBuffer initialiseres til at indeholde stakoplysningerne for hver tråd.
  2. Vi bruger derefter ManagementFabrik klasse for at få instansen af TrådMxBønne. EN ManagementFabrik er en fabriksklasse til at få administrerede bønner til Java-platformen. Derudover er en TrådMxBønne er styringsgrænsefladen til trådsystemet til JVM.
  3. Indstilling lockedMonitors og lockedSynchronizers værdier til rigtigt angiver at fange de synkroniser, der kan ejes, og alle låste skærme i tråddumpen.

5. Konklusion

I denne artikel har vi vist flere måder at fange en tråddump på.

Først diskuterede vi forskellige JDK-hjælpeprogrammer og derefter kommandolinjealternativerne. I det sidste afsnit afsluttede vi den programmatiske tilgang ved hjælp af JMX.

Som altid er den fulde kildekode for eksemplet tilgængelig på GitHub.