Praćenje Java aplikacija pomoću Flight Recorder-a

1. Pregled

U ovom uputstvu ispitat ćemo Java Flight Recorder, njegove koncepte, osnovne naredbe i kako ga koristiti.

2. Uslužni programi za nadzor Java

Java nije samo programski jezik već vrlo bogat ekosustav s puno alata. JDK sadrži programe koji nam omogućuju sastavljanje vlastitih programa, kao i praćenje njihovog stanja i stanja Java virtualnog stroja tijekom punog životnog ciklusa izvršavanja programa.

The kanta za smeće mapa JDK distribucije sadrži, između ostalog, sljedeće programe koji se mogu koristiti za profiliranje i nadzor:

  • Java VisualVM (jvisualvm.exe)
  • JConsole (jconsole.exe)
  • Java kontrola misije (jmc.exe)
  • Alat za dijagnostičku naredbu (jcmd.exe)

Predlažemo da istražite sadržaj ove mape kako biste bili svjesni s kojim alatima raspolažemo. Imajte na umu da je Java VisualVM u prošlosti bio dio distribucije Oracle i Open JDK. Međutim, počevši od Jave 9, JDK distribucije više se ne isporučuju s Java VisualVM. Stoga bismo ga trebali preuzeti odvojeno od web stranice projekta VisualVM otvorenog koda.

U ovom uputstvu usredotočit ćemo se na Java Flight Recorder. Ovo nije prisutno među gore spomenutim alatima, jer nije samostalni program. Njegova je upotreba usko povezana s dva gore navedena alata - Java Mission Control i Diagnostic Command Tools.

3. Java Flight Recorder i njegovi osnovni koncepti

Java Flight Recorder (JFR) alat je za praćenje koji prikuplja informacije o događajima u Java virtualnom stroju (JVM) tijekom izvršavanja Java aplikacije. JFR je dio JDK distribucije i integriran je u JVM.

JFR je dizajniran da što manje utječe na izvedbu pokrenute aplikacije.

Da bismo koristili JFR, trebali bismo ga aktivirati. To možemo postići na dva načina:

  1. prilikom pokretanja Java programa
  2. donošenje dijagnostičkih naredbi od jcmd alat kad je Java program već pokrenut

JFR nema samostalni alat. Koristimo Java Mission Control (JMC), koji sadrži dodatak koji nam omogućuje vizualizaciju podataka koje je prikupio JFR.

Ove tri komponente - JFR, jcmd i JMC - čine cjeloviti paket za prikupljanje podataka o runtovima niske razine pokrenutog Java programa. Ove će nam informacije možda biti vrlo korisne pri optimizaciji našeg programa ili pri dijagnosticiranju kada nešto pođe po zlu.

Ako na računalu imamo instalirane razne verzije Jave, važno je provjerite je li Java kompajler (javac), pokretač Java (Java) i gore spomenuti alati (JFR, jcmd i JMC) potječu iz iste Java distribucije. Inače postoji rizik da nećete moći vidjeti korisne podatke jer JFR formati podataka različitih verzija možda nisu kompatibilni.

JFR ima dva glavna koncepta: događaji i protok podataka. Kratko razgovarajmo o njima.

3.1. Događaji

JFR prikuplja događaje koji se događaju u JVM-u kada se Java aplikacija pokrene. Ti su događaji povezani sa stanjem samog JVM-a ili stanjem programa. Događaj ima ime, vremensku oznaku i dodatne informacije (poput podataka o niti, snopu izvršavanja i stanju hrpe).

Tamo su tri vrste događaja koje JFR prikuplja:

  • trenutni događaj zapisuje se odmah nakon što se dogodi
  • događaj trajanja zapisuje se ako njegovo trajanje prelazi navedeni prag
  • uzorak događaja koristi se za uzorkovanje aktivnosti sustava

3.2. Protok podataka

Događaji koje JFR prikuplja sadrže ogromnu količinu podataka. Iz tog razloga, JFR je prema dizajnu dovoljno brz da ne ometa program.

JFR sprema podatke o događajima u jednu izlaznu datoteku, let.jfr.

Kao što znamo, I / O operacije na disku prilično su skupe. Stoga JFR koristi razne međuspremnike za pohranu prikupljenih podataka prije ispiranja blokova podataka na disk. Stvari mogu postati malo složenije, jer u isto vrijeme program može imati višestruke procese registracije s različitim opcijama.

Zbog ovoga, u izlaznoj datoteci možemo pronaći više podataka nego što je zatraženo ili možda neće biti kronološkim redoslijedom. Mogli bismo i ne primijetiti ovu činjenicu ako koristimo JMC, jer on vizualizira događaje u kronološkom redoslijedu.

U nekim rijetkim slučajevima JFR možda neće uspjeti isprati podatke (na primjer, kada ima previše događaja ili u slučaju nestanka struje). Ako se to dogodi, JFR nas pokušava obavijestiti da u izlaznoj datoteci možda nedostaje dio podataka.

4. Kako se koristi Java Flight Recorder

JFR je eksperimentalna značajka, stoga se njegova uporaba može promijeniti. Zapravo, u ranijim distribucijama moramo aktivirati komercijalne značajke kako bismo ih koristili u proizvodnji. Međutim, počevši od JDK 11, možemo ga koristiti bez ičega aktiviranja. Uvijek se možemo obratiti službenim napomenama o izdanju Java kako bismo provjerili kako se koristi ovaj alat.

Da bi JDK 8 mogao aktivirati JFR, trebali bismo pokrenuti JVM s opcijama + OtključajKomercijalne značajke i + FlightRecorder.

Kao što smo gore spomenuli, postoje dva načina za aktiviranje JFR-a. Kada ga aktiviramo istovremeno s pokretanjem aplikacije, to radimo iz naredbenog retka. Kad je aplikacija već pokrenuta, koristimo dijagnostički alat za naredbe.

4.1. Naredbeni redak

Prvo, sastavljamo program *.Java datoteka u * .razred koristeći standardni java kompajler javac.

Kad kompilacija uspije, program možemo pokrenuti sa sljedećim opcijama:

java -XX: + UnlockCommercialFeatures -XX: + FlightRecorder -XX: StartFlightRecording = trajanje = 200 s, naziv datoteke = flight.jfr put-do-klase-datoteka

gdje put-do-klase-datoteke je ulazna točka aplikacije * .razred datoteka.

Ova naredba pokreće aplikaciju i aktivira snimanje koje započinje odmah i traje najviše 200 sekundi. Prikupljeni podaci spremaju se u izlaznu datoteku, let.jfr. Ostale opcije detaljnije ćemo opisati u sljedećem odjeljku.

4.2. Alat za dijagnostičku naredbu

Također možemo započeti registraciju događaja pomoću jcmd alat. Na primjer:

jcmd 1234 JFR.početak trajanja = 100s naziv datoteke = let.jfr

Prije JDK 11, kako bismo mogli aktivirati JFR na ovaj način, trebali bismo pokrenuti aplikaciju s otključanim komercijalnim značajkama:

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

Jednom kada se aplikacija pokrene, koristimo njezin procesni ID za izvršavanje različitih naredbi koje imaju sljedeći format:

jcmd [parametri]

Evo cjelovitog popisa dijagnostičkih naredbi:

  • JFR.početak - započinje novo JFR snimanje
  • JFR.provjera - provjerava pokretanje JFR snimanja
  • JFR.stop - zaustavlja određeno JFR snimanje
  • JFR.dump - kopira sadržaj JFR snimke u datoteku

Svaka naredba ima niz parametara. Na primjer, JFR.početak naredba ima sljedeće parametre:

  • Ime - naziv snimke; služi za kasnije pozivanje na ovu snimku drugim naredbama
  • odgoditi - dimenzionalni parametar za vremensko kašnjenje početka snimanja, zadana vrijednost je 0s
  • trajanje - dimenzionalni parametar za vremenski interval trajanja snimanja; zadana vrijednost je 0s, što znači neograničeno
  • naziv datoteke - naziv datoteke koja sadrži prikupljene podatke
  • maksaža - dimenzionalni parametar za maksimalnu starost prikupljenih podataka; zadana vrijednost je 0s, što znači neograničeno
  • povećati - maksimalna veličina međuspremnika za prikupljene podatke u bajtovima; zadana vrijednost je 0, što znači da nema maksimalne veličine

Primjer upotrebe ovih parametara već smo vidjeli na početku ovog odjeljka. Potpuni popis parametara možemo uvijek potražiti u službenoj dokumentaciji Java Flight Recorded.

Iako je JFR dizajniran tako da ima što manje otiska na performansama JVM-a i aplikacije, bolje je ograničiti maksimalnu količinu prikupljenih podataka postavljanjem barem jednog od parametara: trajanje, maksaža, ili povećati.

5. Java Flight Recorder u akciji

Pokažimo sada JFR na djelu pomoću primjera programa.

5.1. Primjer programa

Naš program ubacuje objekte na popis do OutOfMemoryError javlja se. Tada program spava jednu sekundu:

javna statička void glavna (String [] args) {Stavke popisa = novi ArrayList (1); probajte {while (true) {items.add (new Object ()); }} catch (OutOfMemoryError e) {System.out.println (e.getMessage ()); } potvrditi predmete.size ()> 0; isprobajte {Thread.sleep (1000); } catch (InterruptedException e) {System.out.println (e.getMessage ()); }}

Bez izvršavanja ovog koda možemo uočiti potencijalni nedostatak: dok petlja će dovesti do velike potrošnje procesora i memorije. Upotrijebimo JFR da vidimo ove nedostatke i vjerojatno pronađemo druge.

5.2. Započnite registraciju

Prvo kompajliramo program izvršavanjem sljedeće naredbe iz naredbenog retka:

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

U ovom bismo trenutku trebali pronaći datoteku FlightRecorder.class u out / com / baeldung / flightrecorder imenik.

Sada ćemo pokrenuti program sa sljedećim opcijama:

java -XX: + UnlockCommercialFeatures -XX: + FlightRecorder -XX: StartFlightRecording = trajanje = 200s, naziv datoteke = flight.jfr -cp ./out/ com.baeldung.flightrecorder.FlightRecorder

5.3. Vizualizirajte podatke

Sada hranimo datoteku let.jfr do Java kontrola misije, koji je dio distribucije JDK. Pomaže nam na lijep i intuitivan način vizualizirati podatke o našim događajima.

Njegov glavni zaslon prikazuje nam informacije o tome kako je program koristio CPU tijekom izvršenja. Vidimo da je CPU bio jako opterećen, što se sasvim očekuje zbog dok petlja:

Na lijevoj strani pogleda vidimo dijelove Općenito, Memorija, Kodirati, i Niti, između ostalih. Svaki odjeljak sadrži razne kartice s detaljnim informacijama. Na primjer, tab Vruće metode odjeljka Kodirati sadrži statistiku poziva metoda:

Na ovoj kartici možemo uočiti još jedan nedostatak našeg primjera programa: metoda java.util.ArrayList.grow (int) pozvan je 17 puta kako bi se povećao kapacitet polja svaki put kad nije bilo dovoljno prostora za dodavanje objekta.

U realističnijim programima možemo vidjeti puno drugih korisnih informacija:

  • statistika o stvorenim objektima, kada ih je sakupljač otpada stvorio i uništio
  • detaljno izvješće o kronologiji niti, kada su zaključane ili aktivne
  • koje je I / O operacije izvršavala aplikacija

6. Zaključak

U ovom smo članku predstavili temu praćenja i profiliranja Java aplikacije pomoću Java Flight Recorder. Ovaj je alat i dalje eksperimentalni, pa bismo za potpunije i novije informacije trebali potražiti njegovo službeno mjesto.

Kao i uvijek, isječak koda dostupan je na našem spremištu Github.