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 vam 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 razumete.

Pokretanjem JConsole-a iskače prozor New Connection sa spiskom Java programa koji trenutno rade na ovoj mašini (kolone PID i Local Process); izaberite jedan (na primer 28966 od tehnološke strane) i kliknite Connect.
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 želite 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žete sa jednim lokalnim programom, u kartici Overview vidite runtime pregled Java programa, sa četiri živa grafikona: Heap Memory Usage, Threads, Classes i CPU Usage.
Nadzor memorije
Kartica Memory ima ulogu vizuelne jstat komande (iz prethodnog poglavlja); služi za nadzor upotrebe Java heap-a. Padajući meni Chart nudi pregled celog heap-a ili pojedinačnih oblasti — oblasti eden, oblasti preživelih i stare generacije, a opis svake oblasti stoji u koloni Legend.
Da bi pregled promena memorije bio jasniji, možete 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 na grafikonu, vidi se da raste lomljenom (testerastom) linijom — kako GC povremeno oslobađa prostor, tako krivulja pada i ponovo raste.
Nakon klika na Perform GC, stubičasti prikaz stare generacije naglo skače — nakon GC-a se objekti iz oblasti Eden sakupljaju, a preživeli premeštaju u staru generaciju, pa njen zauzeti deo privremeno dostiže maksimum.
Nadzor niti
JConsole omogućava i nadzor nad nitima, što odgovara vizuelnoj jstack komandi (iz prethodnog poglavlja).
Kartica Threads prikazuje živi broj niti unutar aplikacije (linija Live Threads na grafikonu, uz Peak i Total Started); dole levo nalazi se spisak svih niti u programu. Klikom na ime niti možete videti informacije o steku te niti, kao i njeno stanje (RUNNABLE, WAITING, BLOCKED...).
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 Threads JConsole-a kliknite na dugme Detect Deadlock — ako je mrtva petlja nastupila, pojaviće se nova kartica sa imenima blokiranih niti, bravicama koje drže i onima koje čekaju.
Stanje učitavanja klasa
Kartica Classes prikazuje ukupan broj učitanih klasa (grafikon Loaded Classes); u detaljima se nalaze i brojevi Total Loaded, Current Loaded i Total Unloaded klasa.
Pregled VM-a
U kartici VM Summary, JConsole prikazuje trenutno okruženje izvršavanja aplikacije — tip virtuelne mašine (VM), verziju (Vendor, VM Version), informacije o heap-u (Heap, NonHeap), vreme rada (Uptime) i kompletnu listu parametara virtuelne mašine (VM arguments).
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

Nakon instalacije i otvaranja, u levom panelu Applications → Local videćete sve Java procese na mašini — dvoklik na proces otvara kartice sa njegovim pregledom.
VisualVM ne zaostaje mnogo za JConsole-om — ne samo da lepše izgleda, već podržava i dodataka.
Klikni na Tools → Plugins, pa u kartici Available Plugins vidite veliki broj dodataka; označi željene, kliknite Install i instalirajte 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; izaberite jedan od sledećih:
① U panelu Applications desni klik na proces → Heap Dump.
② U panelu Applications izaberite aplikaciju, a u kartici Monitor kliknite dugme Heap Dump.
U oba slučaja se u levom panelu, ispod procesa, pojavljuje novi čvor (npr. heapdump-xxx.hprof) sa analitikom zauzeća memorije po klasama.
Ako želite sačuvati fajl snimka heap-a i deliti ga, desni klik na čvor heapdump-a i izaberite Save As...; u suprotnom, kada se VisualVM zatvori, generisani snimak heap-a biće automatski obrisan kao privremeni fajl.
Analiza performansi programa
Ako želite da analizirate CPU i memoriju aplikacije, u kartici „Profiler” kliknite 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. Rezultati se prikazuju sortirani po zauzeću, u obliku Time (za CPU), odnosno Size/Objects (za memoriju), po paketima i metodama.
Napomena: nakon klika na Start (ili Snapshot), vrati se u aplikaciju i obavi radnje. Kada se završe operacije koje želite da analizirate, kliknite na dugme Stop da okončate 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 i pokretanja, otvara se glavni prozor JMC-a: u levom panelu JVM Browser nalazi se spisak lokalnih (i udaljenih) JVM procesa, a dvoklik na MBean Server procesa otvara pregled sa instrument-tablom.
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, pa u kartici Flight Recorder kliknite Start Flight Recording, označi Profiling ili Continuous, podesite trajanje (npr. jedan minut) i pokrenite snimanje performansi.
Po završetku snimanja, JMC automatski otvara snimljeni .jfr fajl: levo se nalazi stablo sa grupama događaja (Memory, Code, Threads, GC...), a u sredini se prikazuju grafikoni i tabele izabrane grupe.
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žete 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žete pogledati u ovom GitHub repozitorijumu:
Na primer, u grupi Memory → Garbage Collections vidi se koja klasa (ovde: java.math.BigDecimal) zauzima najviše memorije, koliko objekata je alocirano i koliko je preživelo GC.
Za dalju analizu izvora zauzeća memorije prebaci se na grupu Threads: označi kolone Allocations i Live Objects i vidite stanje memorije po nitima.
Takođe se vidi da cpu_high_thread ovde neprestano računa brojeve sa pokretnim zarezom, pa u grupi Code zauzima najveći udeo CPU vremena.
Stanje mrtve petlje (deadlock) ovde takođe možete videti, u grupi Threads → Deadlock.
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.
