Različiti načini hvatanja odlagališta Java Java

1. Uvod

U ovom ćemo članku prikazati različite načine za snimanje odlagališta hrpe u Javi.

Dump heap je snimka svih objekata koji se u određenom trenutku nalaze u memoriji JVM-a. Vrlo su korisni za rješavanje problema curenja memorije i optimiziranje korištenja memorije u Java programima.

Heap odlagališta obično se pohranjuju u binarnom formatu hprof datoteka. Te datoteke možemo otvoriti i analizirati pomoću alata poput jhat ili JVisualVM. Također, za korisnike Eclipsea vrlo je često koristiti MAT.

U sljedećim odjeljcima proći ćemo kroz više alata i pristupa za generiranje odlagališta hrpe i prikazat ćemo glavne razlike između njih.

2. Alati JDK

JDK dolazi s nekoliko alata za hvatanje deponija hrpe na različite načine. Svi ovi alati nalaze se ispod kanta za smeće mapa unutar početnog direktorija JDK. Stoga ih možemo pokrenuti iz naredbenog retka sve dok je ovaj direktorij uključen u put sustava.

U sljedećim odjeljcima pokazat ćemo kako koristiti ove alate za hvatanje hrpe odlagališta.

2.1. jmap

jmap je alat za ispis statistike o memoriji u pokrenutom JVM-u. Možemo ga koristiti za lokalne ili udaljene procese.

Da bismo uhvatili odlagalište hrpe pomoću jmapa, trebamo koristiti istovariti opcija:

jmap -dump: [uživo], format = b, datoteka = 

Uz tu opciju trebali bismo navesti nekoliko parametara:

  • uživo: ako je postavljeno, ispisuje samo objekte koji imaju aktivne reference i odbacuje one koji su spremni za sakupljanje smeća. Ovaj parametar nije obavezan
  • format = b: navodi da će dump datoteka biti u binarnom formatu. Ako nije postavljen, rezultat je isti
  • datoteka: datoteka u koju će se zapis izpisati
  • pid: id Java procesa

Primjer bi mogao biti sljedeći:

jmap -dump: uživo, format = b, datoteka = / tmp / dump.hprof 12587

Zapamtite da možemo lako dobiti pid Java procesa pomoću jps naredba.

Imajte na umu dajmap je uveden u JDK kao eksperimentalni alat i nije podržan. Stoga bi u nekim slučajevima bilo poželjno umjesto toga koristiti druge alate.

2.2. jcmd

jcmd je vrlo cjelovit alat koji funkcionira slanjem zahtjeva za naredbe JVM-u. Moramo ga koristiti na istom stroju na kojem je pokrenut Java proces.

Jedna od mnogih naredbi je GC.heap_dump. Možemo ga koristiti za dobivanje izvatka hrpe samo specificiranjem pid procesa i putanje izlazne datoteke:

jcmd GC.heap_dump 

Možemo ga izvršiti s istim parametrima kao i prije:

jcmd 12587 GC.heap_dump /tmp/dump.hprof

Kao i kod jmap, generirani deponij je u binarnom formatu.

2.3. JVisualVM

JVisualVM je alat s grafičkim korisničkim sučeljem koji nam omogućuje nadgledanje, rješavanje problema i profiliranje Java aplikacija. GUI je jednostavan, ali vrlo intuitivan i lak za upotrebu.

Jedna od mnogih opcija omogućuje nam snimanje odlagališta gomile. Ako desnom tipkom miša kliknemo na Java proces i odaberemo "Heap Dump" opcija, alat će stvoriti dump heap i otvoriti ga u novoj kartici:

Primijetite da možemo pronaći put datoteke stvorene u "Osnovne informacije" odjeljak.

Počevši od JDK 9, Visual VM nije uključen u distribucije Oracle JDK i Open JDK. Stoga, ako koristimo Javu 9 ili noviju verziju, JVisualVM možemo dobiti s projektnog web mjesta Visual VM.

3. Automatski snimite odlagalište otpada

Svi alati koje smo prikazali u prethodnim odjeljcima namijenjeni su ručnom hvatanju deponija hrpe u određeno vrijeme. U nekim slučajevima želimo dobiti odlagalište hrpe kada a java.lang.OutOfMemoryError dogodi pa nam pomaže istražiti pogrešku.

U tim slučajevima, Java nudi HeapDumpOnOutOfMemoryError opcija naredbenog retka koja generira izbacivanje hrpe kada a java.lang.OutOfMemoryError bačeno je:

java -XX: + HeapDumpOnOutOfMemoryError

Prema zadanim postavkama sprema odlagalište u java_pid.hprof datoteku u direktoriju u kojem pokrećemo aplikaciju. Ako želimo navesti drugu datoteku ili direktorij, možemo je postaviti u HeapDumpPath opcija:

java -XX: + HeapDumpOnOutOfMemoryError -XX: HeapDumpPath =

Kad našoj aplikaciji ponestane memorije pomoću ove opcije, u zapisnicima ćemo moći vidjeti stvorenu datoteku koja sadrži dump hrpe:

java.lang. na com.baeldung.heapdump.App.main (App.java:7)

U gornjem primjeru je zapisano na java_pid12587.hprof datoteka.

Kao što vidimo, ova je opcija vrlo korisna i pri pokretanju aplikacije s ovom opcijom nema dodatnih troškova. Stoga se preporučuje korištenje ove opcije uvijek, posebno u proizvodnji.

Konačno, ova se opcija također može odrediti za vrijeme izvođenja pomoću HotSpotDiagnostic MBean. Da bismo to učinili, možemo koristiti JConsole i postaviti HeapDumpOnOutOfMemoryError VM opcija za pravi:

Više informacija o MBeansu i JMX-u možemo pronaći u ovom članku.

4. JMX

Posljednji pristup koji ćemo obraditi u ovom članku je korištenje JMX-a. Koristit ćemo HotSpotDiagnostic MBean koje smo ukratko predstavili u prethodnom odjeljku. Ovaj MBean pruža a dumpHeap metoda koji prihvaća 2 parametra:

  • izlazna datoteka: put datoteke za odlagalište. Datoteka bi trebala imati nastavak hprof
  • uživo: ako je postavljeno na true, izbacuje samo aktivne objekte u memoriju, kao što smo vidjeli kod jmap-a prije

U sljedećim odjeljcima prikazat ćemo dva različita načina pozivanja ove metode kako bi se uhvatilo odlagalište hrpe.

4.1. JConsole

Najlakši način za korištenje HotSpotDiagnostic MBean je pomoću JMX klijenta kao što je JConsole.

Ako otvorimo JConsole i povezati se s pokrenutim Java procesom, možemo doći do MBeans i pronađite HotSpotDiagnostic pod, ispod com.sun.upravljanje. U operacijama možemo pronaći dumpHeap metoda koju smo već opisali:

Kao što je prikazano, samo trebamo uvesti parametre izlazna datoteka i uživo u p0 i str1 tekstualna polja kako bi se izvela dumpHeap operacija.

4.2. Programski način

Drugi način korištenja HotSpotDiagnostic MBean je programskim pozivom iz Java koda.

Da bismo to učinili, prvo moramo dobiti MBeanServer instance kako bi se dobio MBean koji je registriran u aplikaciji. Nakon toga, jednostavno moramo dobiti primjerak a HotSpotDiagnosticMXBean i nazovite svoje dumpHeap metoda.

Pogledajmo u kodu:

javna statička void dumpHeap (String filePath, boolean live) baca IOException {MBeanServer server = ManagementFactory.getPlatformMBeanServer (); HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy (poslužitelj, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class); mxBean.dumpHeap (filePath, uživo); }

Primijetite da se datoteka hprof ne može prebrisati. Stoga bismo to trebali uzeti u obzir prilikom stvaranja aplikacije koja ispisuje deponije hrpe. Ako to ne učinimo, dobit ćemo iznimku:

Iznimka u niti "main" java.io.IOException: Datoteka postoji na sun.management.HotSpotDiagnostic.dumpHeap0 (Native Method) na sun.management.HotSpotDiagnostic.dumpHeap (HotSpotDiagnostic.java:60)

5. Zaključak

U ovom smo uputstvu prikazali više načina za snimanje odlagališta hrpe u Javi.

Kao pravilo, ne bismo trebali zaboraviti koristiti HeapDumpOnOutOfMemoryError opcija uvijek kada se pokreću Java programi. U druge svrhe, bilo koji drugi alat može se savršeno koristiti sve dok imamo na umu nepodržani status jmapa.

Kao i uvijek, puni izvorni kod primjera dostupan je na GitHub-u.