Rôzne spôsoby, ako zachytiť skládky Java

1. Úvod

V tomto článku si ukážeme rôzne spôsoby, ako zachytiť haldu v Jave.

Výpis haldy je snímka všetkých objektov, ktoré sú v určitom okamihu v pamäti JVM. Sú veľmi užitočné pri riešení problémov s únikom pamäte a optimalizácii využitia pamäte v aplikáciách Java.

Haldy sa obvykle ukladajú v binárnych formátoch hprof. Tieto súbory môžeme otvoriť a analyzovať pomocou nástrojov ako jhat alebo JVisualVM. Pre používateľov Eclipse je tiež veľmi bežné používať MAT.

V ďalších častiach si prejdeme niekoľko nástrojov a prístupov na generovanie haldy a ukážeme hlavné rozdiely medzi nimi.

2. Nástroje JDK

JDK je dodávaný s niekoľkými nástrojmi na zachytávanie skládok haldy rôznymi spôsobmi. Všetky tieto nástroje sú umiestnené pod kôš priečinok vo vnútri domovského adresára JDK. Preto ich môžeme spustiť z príkazového riadku, pokiaľ je tento adresár zahrnutý v systémovej ceste.

V ďalších častiach si ukážeme, ako používať tieto nástroje na zachytávanie výpisov haldy.

2.1. jmap

jmap je nástroj na tlač štatistík o pamäti v bežiacom JVM. Môžeme ho použiť pre miestne alebo vzdialené procesy.

Na zachytenie haldy pomocou jmap musíme použiť skládka možnosť:

jmap -dump: [live], format = b, file = 

Spolu s touto možnosťou by sme mali určiť niekoľko parametrov:

  • žiť: ak je nastavené, vytlačí iba objekty, ktoré majú aktívne referencie, a zahodí tie, ktoré sú pripravené na zber odpadkov. Tento parameter je voliteľný
  • formát = b: určuje, že súbor výpisu bude v binárnom formáte. Ak nie je nastavený, výsledok je rovnaký
  • spis: súbor, do ktorého sa bude výpis zapisovať
  • pid: id procesu Java

Príklad by mohol byť tento:

jmap -dump: live, format = b, file = / tmp / dump.hprof 12587

Pamätajte, že môžeme ľahko získať pid procesu Java pomocou jps príkaz.

Pamätajte na toProgram jmap bol predstavený v JDK ako experimentálny nástroj a nie je podporovaný. Preto v niektorých prípadoch môže byť lepšie použiť iné nástroje.

2.2. jcmd

jcmd je veľmi kompletný nástroj, ktorý funguje tak, že odosiela požiadavky na príkazy do JVM. Musíme ho použiť na rovnakom stroji, na ktorom je spustený proces Java.

Jedným z mnohých príkazov je GC.heap_dump. Môžeme ho použiť na získanie haldy iba zadaním pid procesu a cestu k výstupnému súboru:

jcmd GC.heap_dump 

Môžeme ho vykonať s rovnakými parametrami, ktoré sme použili predtým:

jcmd 12587 GC.heap_dump /tmp/dump.hprof

Rovnako ako v prípade jmap, vygenerovaný výpis je v binárnom formáte.

2.3. JVisualVM

JVisualVM je nástroj s grafickým užívateľským rozhraním, ktorý nám umožňuje monitorovať, odstraňovať problémy a profilovať Java aplikácie. GUI je jednoduché, ale veľmi intuitívne a ľahko použiteľné.

Jedna z mnohých možností nám umožňuje zachytiť výpis haldy. Ak klikneme pravým tlačidlom myši na proces Java a vyberieme „Heap Dump“ Táto možnosť vytvorí skládku haldy a otvorí ju na novej karte:

Všimnite si, že môžeme nájsť cestu k súboru vytvorenému v "Základné informácie" oddiel.

Počnúc JDK 9 nie je Visual VM zahrnutý v distribúciách Oracle JDK a Open JDK. Preto, ak používame Java 9 alebo novšie verzie, môžeme JVisualVM získať z webovej stránky projektu Visual VM open source.

3. Automaticky zachyťte výpis haldy

Všetky nástroje, ktoré sme si ukázali v predchádzajúcich častiach, sú určené na manuálne zachytávanie výpisov haldy v konkrétnom čase. V niektorých prípadoch chceme získať haldu, keď a java.lang.OutOfMemoryError vyskytne sa, pomáha nám to chybu preskúmať.

Pre tieto prípady Java poskytuje HeapDumpOnOutOfMemoryError voľba príkazového riadku, ktorá generuje výpis haldy, keď a java.lang.OutOfMemoryError je hodená:

java -XX: + HeapDumpOnOutOfMemoryError

V predvolenom nastavení ukladá výpis do a java_pid.hprof súbor v adresári, kde spustíme aplikáciu. Ak chceme určiť iný súbor alebo adresár, môžeme ho nastaviť v HeapDumpPath možnosť:

java -XX: + HeapDumpOnOutOfMemoryError -XX: HeapDumpPath =

Keď našej aplikácii dôjde táto pamäť pomocou tejto možnosti, uvidíme v protokoloch vytvorený súbor, ktorý obsahuje výpis haldy:

java.lang.OutOfMemoryError: Požadovaná veľkosť poľa prekračuje limit VM Vypúšťanie haldy na java_pid12587.hprof ... Výnimka vo vlákne „hlavný“ Vytvorený súbor s výpisom haldy [4744371 bajtov za 0,029 s] java.lang.OutOfMemoryError: Požadovaná veľkosť poľa prekračuje limit VM na com.baeldung.heapdump.App.main (App.java:7)

Vo vyššie uvedenom príklade bol napísaný na server java_pid12587.hprof spis.

Ako vidíme, táto možnosť je veľmi užitočná a pri spustení aplikácie s touto možnosťou nevznikajú žiadne režijné náklady. Preto sa dôrazne odporúča používať túto možnosť vždy, najmä vo výrobe.

Nakoniec túto možnosť je možné určiť aj za behu programu pomocou HotSpotDiagnostic MBean. K tomu môžeme použiť JConsole a nastaviť HeapDumpOnOutOfMemoryError Možnosť VM pravda:

Viac informácií o MBeans a JMX nájdete v tomto článku.

4. JMX

Posledným prístupom, ktorému sa v tomto článku budeme venovať, je použitie JMX. Použijeme HotSpotDiagnostic MBean ktoré sme v krátkosti predstavili v predchádzajúcej časti. Tento MBean poskytuje dumpHeap metóda ktorý akceptuje 2 parametre:

  • výstupný súbor: cesta k súboru pre výpis. Súbor by mal mať príponu hprof
  • žiť: ak je nastavená na hodnotu true, vypíše iba aktívne objekty z pamäte, ako sme to už videli v prípade jmap

V ďalších častiach si ukážeme 2 rôzne spôsoby, ako vyvolať túto metódu, aby sme zachytili výpis haldy.

4.1. JConsole

Najjednoduchší spôsob použitia HotSpotDiagnostic MBean používa klienta JMX, napríklad JConsole.

Ak otvoríme JConsole a pripojiť sa k spustenému procesu Java, môžeme prejsť na MBeans kartu a vyhľadajte HotSpotDiagnostic pod com.sun.manažment. V prevádzkach nájdeme dumpHeap metóda, ktorú sme už opísali:

Ako je znázornené, musíme len predstaviť parametre výstupný súbor a žiť do p0 a p1 textové polia za účelom vykonania dumpHeap prevádzka.

4.2. Programový spôsob

Ďalším spôsobom použitia HotSpotDiagnostic MBean je vyvolaný programovo z kódu Java.

Aby sme to mohli urobiť, musíme si najskôr zaobstarať MBeanServer napríklad za účelom získania MBean, ktorý je zaregistrovaný v aplikácii. Potom, jednoducho potrebujeme získať inštanciu a HotSpotDiagnosticMXBean a zavolaj jeho dumpHeap metóda.

Pozrime sa na to v kóde:

public static void dumpHeap (String filePath, boolean live) vyvolá IOException {MBeanServer server = ManagementFactory.getPlatformMBeanServer (); HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy (server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class); mxBean.dumpHeap (filePath, live); }

Všimnite si, že súbor hprof nemožno prepísať. Preto by sme to mali brať do úvahy pri vytváraní aplikácie, ktorá tlačí haldy skládok. Ak to neurobíme, dostaneme výnimku:

Výnimka vo vlákne „main“ java.io.IOException: Súbor existuje na adrese sun.management.HotSpotDiagnostic.dumpHeap0 (natívna metóda) na adrese sun.management.HotSpotDiagnostic.dumpHeap (HotSpotDiagnostic.java:60)

5. Záver

V tomto tutoriáli sme si ukázali niekoľko spôsobov, ako zachytiť výpis haldy v Jave.

Ako základné pravidlo by sme mali pamätať na použitie súboru HeapDumpOnOutOfMemoryError voľba vždy, keď sú spustené Java aplikácie. Na iné účely je možné perfektne použiť ktorýkoľvek z ďalších nástrojov, ak si uvedomíme nepodporovaný stav súboru jmap.

Celý zdrojový kód príkladov je ako vždy k dispozícii na serveri GitHub.


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