Virtuální paměť JVM je rozdělena do tří hlavních částí

  • Heap space
  • PermGen (Method area)
  • Native area

Pro sledování toho jak je paměť využívána lze použít různé nástroje např. JConsole nebo VisualVM.JUtH_20121024_RuntimeDataAreas_1_MemoryModel

Heap space

Heap je asi nejznámější část paměti. Jsou zde ukládány všechny objekty, které se za běhu aplikace vytvářejí. Také obsahuje všechny objekty sdílené vlákny.

Konfigurace

Nedostatečná velikost heapu produkuje známou chybu java.lang.OutOfMemoryError: Java heap space, ta se dá odstranit navýšením velikosti heapu pomocí parametru JVM -Xmx (např. pro velikost heapu 1024MB -Xmx1024m).

Dále jde nastavit počáteční velikost heapu při startu aplikace pomocí parametru -Xms. Takto nastavená paměť bude alokována ihned při startu JVM a další paměť bude doalokovavána až v případě potřeby. Pro tomcat je vhodné, aby hodnota tohoto parametru neměla méně než 50% z -Xmx, protože během startu se potřeba paměti rychle zvyšuje a musí být doalokovávána.

Jak to funguje

Heap je rozdělen na více částí. Za zmínku stojí zejména young generation, eden a old generation. Každý vytvořený objekt se během svého životního cyklu mezi těmito částmi přesouvá. Nově vytvořené objekty jsou umístěny v edenu. Většina objektů jako lokální proměnné se příliš dlouho nepoužívají, proto se garbage collecting provádí hlavně v této části. Pokud se objekt používá dostatečně dlouho je přesunut do survivor space a poté do old generation.

Více informací o provádění garbage collectingu je zde. Za zmínku stojí říct, že provádění collectingu je výpočetně velmi náročná operace a měla by být prováděna co nejméně.

Pro běh aplikace je optimální, pokud se velikost dostupné paměti (využitá paměť – max. heap) těsně po provedení collectingu pohybuje okolo 50%.

PermGen

Velikost permgenu je nezávislá na heapu a lze ji upravit parametrem -XX:MaxPermSize. Paměť je sdílená mezi vlákny a jsou zde uloženy hlavně třídy, metadata a metody.  I v této části paměti se spouští GC, lze jej vypnout pomocí parametru -noclassgc.

S nedostatečnou velikostí permgenu je opět spojena známá výjimka java.lang.OutOfMemoryError: PermGen space. K této chybě dochází zejména při opakovaném nasazování aplikace na aplikační server, protože GC nedokáže uvolnit všechna data a pomalu tak dochází k vyčerpání veškeré dostupné paměti. Navyšování velikosti permgenu v tomto případě problém nevyřeší ale pouze oddálí. Jediné řešení je provedené restartu aplikačního serveru.

Native area

Tato oblast je obvykle využívána JVM pro jeho interní operace a provádění kódu aplikace. Taky se zde ukládají privátní data jednotlivých vláken a lokální proměnné primitivních datových typů.