Alatke za nadzor performansi JVM-a — vizuelni deo
Prethodno smo obradili alatke za nadzor performansi JVM-a — deo za komandnu liniju; u ovom tekstu predstavljamo neke vizuelne alatke za nadzor performansi, uključujući JConsole, VisualVM, Java Mission Control itd., dok Arthas iz Alija ostavljamo za posebno poglavlje koje sledi.
Ono u čemu su vizuelne alatke jače od alatki komandne linije jeste što pružaju pregledniji i razumljiviji prikaz podataka o performansama — golim okom se problem brzo uoči; ovaj tekst će ti pokazati moć tih alatki.
JConsole
JConsole (Java Monitoring and Management Console) vizuelna je alatka za nadzor i upravljanje, zasnovana na JMX (Java Management Extensions).
Puno ime JMX-a jeste Java Management Extensions; u prevodu to znači „proširenja za upravljanje Javom”; to je standard, specifikacija, ali i interfejs i okvir za upravljanje sistemima u Javi. JConsole je, recimo, jedna implementacija JMX-a.
JConsole se može koristiti za nadzor stanja rada Java aplikacija, uključujući upotrebu memorije, stanje niti, učitavanje klasa, GC itd., a omogućava i osnovnu analizu performansi.
Povezivanje JConsole-a sa Java programom
JConsole se nalazi u direktorijumu %JAVA_HOME%\bin; pošto je moj trenutni operativni sistem macOS, koji se nešto razlikuje od Windowsa, neću namerno praviti snimke ekrana za Windows — nadam se da razumeš.

Pokretanjem JConsole-a iskače prozor sa spiskom Java programa koji trenutno rade na ovoj mašini; izaberi jedan (na primer 28966 od tehnološke strane) i klikni Poveži se.

Moguće je i udaljeno povezivanje — na primer, za nadzor Java programa na serveru; pritom je potrebno da Java program na udaljenom serveru pri pokretanju dobije sledeće parametre:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=<PORT>
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false<PORT>je broj porta na kojem želiš da JMX agent sluša, na primer 9999.authenticate=falseznači da za povezivanje na JMX nije potrebna autentifikacija (napomena: u produkcionom okruženju to može biti nesigurno).ssl=falseznači da se ne koristi SSL šifrovana veza (takođe, u produkcionom okruženju to može biti nesigurno).
Pregled Java programa
Kada JConsole povežeš sa jednim lokalnim programom, u kartici Pregled vidiš runtime pregled Java programa, uključujući grafikone zauzeće heap memorije, niti, klase i zauzeće CPU-a.

Nadzor memorije
Kartica Memorija ima ulogu vizuelne jstat komande (iz prethodnog poglavlja); služi za nadzor upotrebe Java heap-a, sa mogućnošću detaljnijeg pregleda oblasti eden, oblasti preživelih i stare generacije.

Da bi pregled promena memorije bio jasniji, možeš pokrenuti sledeći kod, pa povezati alatku:
/**
* VM parametri: -Xms100m -Xmx100m -XX:+UseSerialGC
*/
class JConcoleRAMMonitor {
/***
* Objekat rezerviše mesto u memoriji; jedan OOMObject zauzima oko 64 KB
*/
static class OOMObject {
public byte[] placeholder = new byte[64 * 1024];
}
public static void fillHeap(int num) throws InterruptedException {
List<OOMObject> list = new ArrayList<OOMObject>();
for (int i = 0; i < num; i++) {
// kraća pauza, da promene na krivulji nadzora budu uočljivije
Thread.sleep(300);
list.add(new OOMObject());
}
System.gc();
}
public static void main(String[] args) throws Exception {
fillHeap(2000);
}
}Ovaj kod puni Java heap podacima brzinom od 64 KB / 50 ms, ukupno 2000 puta.
Posmatrajući trend oblasti Eden, vidi se da raste lomljenom linijom.

Nakon klika na „Izvrši GC”, stubičasti prikaz stare generacije doseže maksimum, jer se nakon GC-a objekti iz oblasti Eden sakupljaju, a preživeli premeštaju u staru generaciju.

Nadzor niti
JConsole omogućava i nadzor nad nitima, što odgovara vizuelnoj jstack komandi (iz prethodnog poglavlja).
Kao na slici, JConsole prikazuje broj niti unutar aplikacije; dole levo nalazi se spisak svih niti u programu. Klikom na ime niti možeš videti informacije o steku te niti.

Sa JConsole-om je moguće brzo locirati i problem mrtve petlje (deadlock). U prethodnom tekstu napisali smo jedan primer mrtve petlje; ovde ćemo ga ponovo pogledati.
class DeadLockDemo {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock1) {
System.out.println("Nit 1 dobija bravicu 1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("Nit 1 dobija bravicu 2");
}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
System.out.println("Nit 2 dobija bravicu 2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("Nit 2 dobija bravicu 1");
}
}
}).start();
}
}Pokreni ovaj kod, a zatim u kartici niti JConsole-a klikni na dugme „Detektuj mrtvu petlju” i videćeš informacije o mrtvoj petlji među nitima.

Stanje učitavanja klasa
Kao na slici, kartica Klase prikazuje broj učitanih klasa; u detaljima se nalazi i broj klasa koje su istovarene.

Pregled VM-a
U kartici Pregled VM-a, JConsole prikazuje trenutno okruženje izvršavanja aplikacije, uključujući tip virtuelne mašine, verziju, informacije o heap-u, kao i parametre virtuelne mašine.

VisualVM
VisualVM (All-in-One Java Troubleshooting Tool) jedna je od moćnih alatki za nadzor rada i rešavanje problema; dugo vremena VisualVM je bio zvanično od Oracle-a preporučena alatka za rešavanje problema.
Integriše funkcije više JDK alatki komandne linije i pruža prijateljsko grafičko okruženje, zbog čega je vrlo pogodan za razvojna i produkciona okruženja.
Instalacija dodataka za VisualVM
Instalacija VisualVM-a vrlo je jednostavna; adresa za preuzimanje: https://visualvm.github.io

Izgled nakon instalacije i otvaranja:

VisualVM ne zaostaje mnogo za JConsole-om — ne samo da lepše izgleda, već podržava i dodataka.
Klikni na tools -> plugins, pa u dostupnim dodacima vidiš veliki broj dodataka; instaliraj po potrebi.

Kartice Pregled, Nadzor i Niti u VisualVM-u ne razlikuju se bitno od onih u JConsole-u, pa o njima nećemo ponovo.
Generisanje i pregled snimka heap-a
U VisualVM-u snimak heap-a (Heap Dump) može se generisati na dva načina; izaberi jedan od sledećih:
①,U panelu Aplikacije desni klik i izaberi Heap Dump.

②,U panelu Aplikacije izaberi aplikaciju, a u panelu „Nadzor” klikni Heap Dump.

Ako želiš sačuvati fajl snimka heap-a i deliti ga, desni klik na čvor heapdump i izaberi „Sačuvaj kao”; u suprotnom, kada se VisualVM zatvori, generisani snimak heap-a biće automatski obrisan kao privremeni fajl.

Analiza performansi programa
Ako želiš da analiziraš CPU i memoriju aplikacije, u kartici „Profiler” klikni na „CPU” ili „Memory”, pa će VisualVM tokom tog vremena zabeležiti sve metode koje je aplikacija izvršila.
Tako će, na primer, CPU izračunati broj izvršavanja i trajanje svake metode; memorija će izračunati stanje alokacije memorije po metodi.

Napomena: nakon klika na start, vrati se u aplikaciju i obavi radnje. Kada se završe operacije koje želiš da analiziraš, klikni na dugme „Zaustavi” da okončaš nadzor.
Java Mission Control
JMC je isprva bio alatka za dijagnostiku u JRockit VM, ali je od Oracle JDK 7 Update 4 veza za HotSpot VM. Kasnije ga je Oracle ponovo učinio open-source-om kao zaseban proizvod.
GitHub adresa: https://github.com/openjdk/jmc

Zvanično Oracle preuzimanje prilično je sporo; preuzimanje je moguće i preko jdk.java.net.
Nakon raspakivanja, pokretanje prikazuje sledeći interfejs:

MBean Server
Klikni na MBean Server lokalnog procesa:

MBean jeste standardni način upravljanja Java aplikacijama i deo je proširenja za upravljanje Javom (JMX). MBean predstavlja upravljive Java objekte; njihova svojstva i operacije mogu se pristupati preko JMX-a.
Instrument tabla prikazuje iskorišćenost Java heap-a, iskorišćenost CPU-a i Live Set+Fragmentation (Live Set jeste veličina preživelih objekata, Fragmentation veličina fragmenata).
Flight Recorder
Flight Recorder (JFR) dodatna je funkcija koju pruža JMC; putem snimanja rada aplikacije u određenom vremenskom intervalu, a zatim analize i prikaza, moguće je još detaljnije analizirati i dijagnostikovati performanse aplikacije.
Da bi se koristio JFR, program pri pokretanju mora dobiti sledeće parametre:
-XX:+UnlockCommercialFeatures -XX:+FlightRecorderPoveži se sa programom koji je pokrenut sa ovim parametrima, pokreni snimanje leta i uradi jednominutno snimanje performansi:

Po završetku snimanja, JMC automatski otvara upravo snimljeno:

Kvalitet podataka koje pruža JFR obično je i veći od onoga koji druge alatke dobijaju uzorkovanjem preko agenta.
Pri sakupljanju smeća, na primer, u MBean-u HotSpot-a obično postoje podaci o veličinama pojedinih generacija, broju sakupljanja, vremenu, zauzeću itd., koji spadaju u informacije tipa „rezultat”; u JFR-u se, pak, može videti i koji su objekti u tom intervalu alocirani, a koji sakupljeni — što spada u informacije tipa „proces”.
Ovde iznosim neki kod za testiranje; možeš ga pokrenuti lokalno i videti efekat JFR-a.
Prvi: preveliko zauzeće CPU-a:
/**
* Nit koja troši CPU
* Neprestano vrti petlju s operacijama s pokretnim zarezom
*/
private static void cpuHigh() {
Thread thread = new Thread(() -> {
Thread.currentThread().setName("cpu_high_thread");
while (true){
double pi = 0;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
pi += Math.pow(-1, i) / (2 * i + 1);
}
System.out.println("Pi: " + pi * 4);
}
});
thread.start();
}Drugi: preveliko zauzeće memorije:
/**
* Neprestano dodaje BigDecimal u listu
*/
private static void allocate() {
new Thread(()->{
Thread.currentThread().setName("memory_allocate_thread");
List<BigDecimal> list = new ArrayList<>();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
list.add(new BigDecimal(i));
}
}).start();
}Kompletan primer možeš pogledati u ovom GitHub repozitorijumu:
Na primer, kroz panel „Memorija” vidi se da objekat BigDecimal zauzima najviše memorije.

Za dalju analizu izvora zauzeća memorije prebaci se na stranicu niti; označi tri kućice i u odeljku memorije vidiš stanje memorije.

Takođe se vidi da cpu_high_thread ovde neprestano računa brojeve sa pokretnim zarezom, pa zauzima više CPU-a.

Stanje mrtve petlje ovde takođe možeš videti.

Alatke trećih strana
Gornje tri zvanične su Oracle-ove alatke za nadzor performansi; pored njih postoje i alatke trećih strana.
- „MAT”
Alatka za analizu Java heap memorije.
- „GChisto”
Alatka za analizu GC logova.
- „GCViewer”
Alatka za analizu GC logova.
- „JProfiler”
Komercijalno oruđe za analizu performansi.
- „arthas”
Alatka za dijagnostiku iz Alija, open-source.
- „async-profiler”
Alatka za analizu performansi Java aplikacija; open-source, grafikoni plamena, višeplatformska.
Kratak pregled
U ovom tekstu predstavili smo neke vizuelne alatke za nadzor performansi, uključujući JConsole, VisualVM, Java Mission Control itd.; Arthas iz Alija ostavljamo za posebno poglavlje koje sledi.
Referenca: gost Zvezda Sanfene na Alatke za nadzor performansi — vizuelni deo
