Monitoring van Java-applicaties met Flight Recorder

1. Overzicht

In deze zelfstudie onderzoeken we Java Flight Recorder, de concepten, de basisopdrachten en het gebruik ervan.

2. Java-monitoringprogramma's

Java is niet alleen een programmeertaal, maar een zeer rijk ecosysteem met veel tools. De JDK bevat programma's waarmee we onze eigen programma's kunnen compileren, en ook hun toestand en de staat van de Java Virtual Machine kunnen volgen gedurende de volledige levenscyclus van programma-uitvoering.

De bak map van een JDK-distributie bevat onder andere de volgende programma's die kunnen worden gebruikt voor profilering en monitoring:

  • Java VisualVM (jvisualvm.exe)
  • JConsole (jconsole.exe)
  • Java Mission Control (jmc.exe)
  • Diagnostisch opdrachtprogramma (jcmd.exe)

We raden u aan de inhoud van deze map te verkennen om u ervan bewust te zijn welke tools we tot onze beschikking hebben. Houd er rekening mee dat de Java VisualVM in het verleden deel uitmaakte van de Oracle- en Open JDK-distributies. Echter, vanaf Java 9 worden JDK-distributies niet langer geleverd met Java VisualVM. Daarom moeten we het apart downloaden van de VisualVM open source projectwebsite.

In deze tutorial zullen we ons concentreren op de Java Flight Recorder. Dit is niet aanwezig bij de hierboven genoemde tools omdat het geen op zichzelf staand programma is. Het gebruik ervan hangt nauw samen met twee van de bovenstaande tools: Java Mission Control en Diagnostic Command Tools.

3. Java Flight Recorder en zijn basisconcepten

Java Flight Recorder (JFR) is een monitoringtool die verzamelt informatie over de gebeurtenissen in een Java Virtual Machine (JVM) tijdens de uitvoering van een Java-applicatie. JFR maakt deel uit van de JDK-distributie en is geïntegreerd in de JVM.

JFR is ontworpen om de prestaties van een actieve applicatie zo min mogelijk te beïnvloeden.

Om JFR te gebruiken, moeten we het activeren. We kunnen dit op twee manieren bereiken:

  1. bij het starten van een Java-applicatie
  2. het doorgeven van diagnostische commando's van het jcmd tool als er al een Java-applicatie actief is

JFR heeft geen zelfstandige tool. We gebruiken Java Mission Control (JMC), dat een plug-in bevat waarmee we de gegevens die door JFR zijn verzameld, kunnen visualiseren.

Deze drie componenten - JFR, jcmd en JMC - een complete suite vormen voor het verzamelen van low-level runtime-informatie van een draaiend Java-programma. We kunnen deze informatie erg handig vinden bij het optimaliseren van ons programma, of bij het diagnosticeren wanneer er iets misgaat.

Als we verschillende versies van Java op onze computer hebben geïnstalleerd, is het belangrijk om zorg ervoor dat de Java-compiler (Javac), het Java-opstartprogramma (Java) en de bovengenoemde tools (JFR, jcmd en JMC) zijn afkomstig uit dezelfde Java-distributie. Anders bestaat het risico dat u geen bruikbare gegevens kunt zien, omdat de JFR-gegevensindelingen van verschillende versies mogelijk niet compatibel zijn.

JFR heeft twee hoofdconcepten: gebeurtenissen en gegevensstroom. Laten we ze kort bespreken.

3.1. Evenementen

JFR verzamelt gebeurtenissen die plaatsvinden in de JVM wanneer de Java-toepassing wordt uitgevoerd. Deze gebeurtenissen zijn gerelateerd aan de staat van de JVM zelf of de staat van het programma. Een evenement heeft een naam, een tijdstempel en aanvullende informatie (zoals threadinformatie, uitvoeringsstapel en status van de heap).

Er zijn drie soorten evenementen dat JFR verzamelt:

  • een instant evenement wordt onmiddellijk geregistreerd zodra het zich voordoet
  • een duur evenement wordt geregistreerd als de duur ervan een bepaalde drempel overschrijdt
  • een voorbeeldevenement wordt gebruikt om de systeemactiviteit te bemonsteren

3.2. Informatiestroom

De gebeurtenissen die JFR verzamelt, bevatten een enorme hoeveelheid gegevens. Om deze reden is JFR door zijn ontwerp snel genoeg om het programma niet te belemmeren.

JFR slaat gegevens over de gebeurtenissen op in een enkel uitvoerbestand, flight.jfr.

Zoals we weten, zijn schijf-I / O-bewerkingen vrij duur. Daarom gebruikt JFR verschillende buffers om de verzamelde gegevens op te slaan voordat de gegevensblokken naar schijf worden gewist. Het kan een beetje ingewikkelder worden omdat een programma op hetzelfde moment meerdere registratieprocessen met verschillende opties kan hebben.

Door dit, we kunnen meer gegevens in het uitvoerbestand vinden dan gevraagd, of het is mogelijk niet in chronologische volgorde. We merken dit feit misschien niet eens als we JMC gebruiken, omdat het de gebeurtenissen in chronologische volgorde visualiseert.

In sommige zeldzame gevallen kan JFR de gegevens niet leegmaken (bijvoorbeeld bij teveel gebeurtenissen of bij stroomuitval). Als dit gebeurt, probeert JFR ons te informeren dat er mogelijk een stukje gegevens in het uitvoerbestand ontbreken.

4. Hoe Java Flight Recorder te gebruiken

JFR is een experimentele functie, daarom kan het gebruik ervan worden gewijzigd. In eerdere distributies moesten we zelfs commerciële functies activeren om deze in productie te kunnen gebruiken. Vanaf JDK 11 kunnen we het echter gebruiken zonder iets te activeren. We kunnen altijd de officiële Java-releaseopmerkingen raadplegen om te controleren hoe u deze tool kunt gebruiken.

Voor JDK 8, om JFR te kunnen activeren, moeten we de JVM starten met de opties + Ontgrendel commerciële functies en + FlightRecorder.

Zoals we hierboven hebben vermeld, zijn er twee manieren om JFR te activeren. Wanneer we het gelijktijdig activeren met het starten van de applicatie, doen we het vanaf de opdrachtregel. Als de applicatie al draait, gebruiken we de diagnostische opdrachttool.

4.1. Opdrachtregel

Eerst compileren we de programma's *.Java bestand in een *.klasse met behulp van de standaard java-compiler Javac.

Zodra de compilatie is gelukt, kunnen we het programma starten met de volgende opties:

java -XX: + UnlockCommercialFeatures -XX: + FlightRecorder -XX: StartFlightRecording = duur = 200s, bestandsnaam = flight.jfr pad-naar-klasse-bestand

waar pad-naar-klasse-bestand is het startpunt van de applicatie *.klasse het dossier.

Deze opdracht start de applicatie en activeert de opname, die onmiddellijk start en niet langer dan 200 seconden duurt. Verzamelde gegevens worden opgeslagen in een uitvoerbestand, flight.jfr. In de volgende sectie zullen we de andere opties in meer detail beschrijven.

4.2. Diagnostisch opdrachtprogramma

We kunnen ook beginnen met het registreren van de evenementen door de jcmd gereedschap. Bijvoorbeeld:

jcmd 1234 JFR.start duur = 100s bestandsnaam = flight.jfr

Voorafgaand aan JDK 11, om JFR op deze manier te kunnen activeren, moeten we de applicatie starten met ontgrendelde commerciële functies:

java -XX: + UnlockCommercialFeatures -XX: + FlightRecorder -cp ./out/ com.baeldung.Main

Zodra de applicatie draait, gebruiken we zijn proces-ID om verschillende commando's uit te voeren, die het volgende formaat aannemen:

jcmd [parameters]

Hier is een volledige lijst van de diagnostische opdrachten:

  • JFR.start - start een nieuwe JFR-opname
  • JFR. Controleren - controleert lopende JFR-opname (s)
  • JFR. Stop - stopt een specifieke JFR-opname
  • JFR.dump - kopieert de inhoud van een JFR-opname naar een bestand

Elk commando heeft een reeks parameters. Bijvoorbeeld de JFR.start commando heeft de volgende parameters:

  • naam - de naam van de opname; het dient om later met andere commando's naar deze opname te kunnen verwijzen
  • vertraging - dimensionale parameter voor een vertraging van de start van de opname, de standaardwaarde is 0s
  • looptijd - dimensionale parameter voor een tijdsinterval van de duur van de opname; de standaardwaarde is 0s, wat onbeperkt betekent
  • bestandsnaam - de naam van een bestand dat de verzamelde gegevens bevat
  • maxage - dimensionale parameter voor de maximale leeftijd van verzamelde gegevens; de standaardwaarde is 0s, wat onbeperkt betekent
  • maxsize - de maximale grootte van buffers voor verzamelde gegevens in bytes; de standaardwaarde is 0, wat betekent dat er geen maximale grootte is

Aan het begin van deze sectie hebben we al een voorbeeld gezien van het gebruik van deze parameters. Voor de volledige lijst van parameters kunnen we altijd de officiële documentatie van Java Flight Recorded raadplegen.

Hoewel JFR is ontworpen om zo min mogelijk invloed te hebben op de prestaties van de JVM en de applicatie, is het beter om de maximale hoeveelheid verzamelde gegevens te beperken door ten minste een van de parameters in te stellen: looptijd, maxage, of maxsize.

5. Java Flight Recorder in actie

Laten we nu JFR in actie demonstreren door een voorbeeldprogramma te gebruiken.

5.1. Voorbeeldprogramma

Ons programma voegt objecten in een lijst in tot een Onvoldoende geheugen fout treedt op. Daarna slaapt het programma een seconde:

public static void main (String [] args) {Lijstitems = nieuwe ArrayList (1); probeer {while (true) {items.add (new Object ()); }} catch (OutOfMemoryError e) {System.out.println (e.getMessage ()); } assert items.size ()> 0; probeer {Thread.sleep (1000); } catch (InterruptedException e) {System.out.println (e.getMessage ()); }}

Zonder deze code uit te voeren, kunnen we een mogelijk nadeel ontdekken: het terwijl loop zal leiden tot een hoog CPU- en geheugengebruik. Laten we JFR gebruiken om deze nadelen te zien en waarschijnlijk andere te vinden.

5.2. Begin met registreren

Eerst compileren we ons programma door de volgende opdracht uit te voeren vanaf de opdrachtregel:

javac -d uit -sourcepath src / main src / main / com / baeldung / flightrecorder / FlightRecorder.java

Op dit punt zouden we een bestand moeten vinden FlightRecorder.class in de out / com / baeldung / flightrecorder directory.

Nu starten we het programma met de volgende opties:

java -XX: + UnlockCommercialFeatures -XX: + FlightRecorder -XX: StartFlightRecorder = duur = 200s, bestandsnaam = flight.jfr -cp ./out/ com.baeldung.flightrecorder.FlightRecorder

5.3. Visualiseer gegevens

Nu voeden we het bestand flight.jfr naar Java Mission Control, dat deel uitmaakt van de JDK-distributie. Het helpt ons om de gegevens over onze evenementen op een leuke en intuïtieve manier te visualiseren.

Het hoofdscherm toont ons de informatie over hoe het programma de CPU gebruikte tijdens de uitvoering. We zien dat de CPU zwaar werd belast, wat redelijk verwacht wordt vanwege de terwijl lus:

Aan de linkerkant van de weergave zien we secties Algemeen, Geheugen, Code, en Draden, onder andere. Elke sectie bevat verschillende tabbladen met gedetailleerde informatie. Bijvoorbeeld tab Hete methoden van sectie Code bevat de statistieken van methodeaanroepen:

Op dit tabblad zien we nog een nadeel van ons voorbeeldprogramma: methode java.util.ArrayList.grow (int) is 17 keer gebeld om de arraycapaciteit te vergroten telkens als er niet genoeg ruimte was om een ​​object toe te voegen.

In meer realistische programma's kunnen we veel andere nuttige informatie zien:

  • statistieken over gemaakte objecten, wanneer ze zijn gemaakt en vernietigd door de garbage collector
  • een gedetailleerd rapport over de chronologie van de discussies, wanneer ze vergrendeld of actief waren
  • welke I / O-bewerkingen de toepassing uitvoerde

6. Conclusie

In dit artikel hebben we het onderwerp van het monitoren en profileren van een Java-applicatie met behulp van Java Flight Recorder geïntroduceerd. Deze tool blijft een experimentele tool, dus we moeten de officiële site raadplegen voor meer volledige en recente informatie.

Zoals altijd is het codefragment beschikbaar in onze Github-repository.


$config[zx-auto] not found$config[zx-overlay] not found