Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Plány Basic, Standarda Enterprise vstoupily do důchodového období 17. března 2025. Další informace najdete v oznámení o vyřazení Azure Spring Apps.
Tento článek se vztahuje na:✅ Basic/Standard ❎ Enterprise
Tento článek popisuje různé koncepty související se správou paměti Java, které vám pomůžou pochopit chování aplikací v Javě hostovaných v Azure Spring Apps.
Model paměti Java
Paměť aplikace v Javě má několik částí a existují různé způsoby rozdělení částí. Tento článek popisuje paměť Javy rozdělenou do paměti haldy, paměti bez haldy a přímé paměti.
Paměť haldy
Paměť haldy ukládá všechny instance a pole tříd. Každý virtuální počítač Java (JVM) má pouze jednu oblast haldy, která se sdílí mezi vlákny.
Aktuátor Spring Boot může sledovat hodnotu haldy paměti. Spring Boot Actuator získává hodnotu haldy jako součást jvm.memory.used/committed/max. Další informace najdete v části jvm.memory.used/committed/max v nástrojích pro řešení problémů s pamětí.
Halda paměti je rozdělena na mladou generaci a starou generaci. Tyto termíny jsou popsány v následujícím seznamu spolu se souvisejícími termíny.
Mladá generace: všechny nové objekty jsou přiděleny a ve věku mladé generace.
- Eden space: nové objekty jsou přiděleny v Eden space.
- Přeživší prostor: objekty se přesunou z Edenu do prostoru přeživšího po přežití jednoho cyklu uvolňování paměti. Přeživší prostor lze rozdělit na dvě části: s1 a s2.
Stará generace: označuje se také jako tenurovaný prostor. Objekty, které zůstaly v přeživších prostorech po dlouhou dobu, budou přesunuty do staré generace.
Před Javou 8 byla další částí haldy také sekce zvaná permanentní generace. Počínaje verzí Java 8 byla permanentní generace vyměněna za metaprostor mimo haldu.
Paměť mimo haldu
Paměť mimo haldu je rozdělena do následujících částí:
Část nehaldové paměti, která nahradila trvalou generaci (nebo permGen) od verze Java 8. Spring Boot Actuator sleduje tuto část a považuje ji za součást
jvm.memory.used/committed/max. Jinými slovy,jvm.memory.used/committed/maxje součet paměti haldy a bývalý permGen část paměti bez haldy. Bývalá trvalá generace se skládá z následujících částí:- Metaspace, které ukládá definice tříd načtené zavaděči tříd.
- Komprimovaný prostor tříd, který je určen pro komprimované ukazatele tříd.
- Mezipaměť kódu, která ukládá nativní kód zkompilovaný JIT.
Jiná paměť, jako je zásobník vláken, který není pozorován pomocí ovladače Spring Boot.
Přímá paměť
Přímá paměť je nativní paměť přidělená java.nio.DirectByteBuffer, která se používá v knihovnách třetích stran, jako je NIO a gzip.
Poháněcího zařízení Spring Boot není pozorována hodnota přímé paměti.
Následující diagram shrnuje model paměti Java popsaný v předchozí části.
Uvolňování paměti v jazyce Java
Existují tři termíny týkající se uvolňování paměti Java (GC): "Minor GC", "Major GC" a "Full GC". Tyto termíny nejsou jasně definovány ve specifikaci prostředí JVM. Tady považujeme "Major GC" a "Full GC" za ekvivalentní.
Menší garbage collection se provádí, když je Eden space plný. Odstraní všechny mrtvé objekty v mladé generaci, a přesune živé objekty z prostoru Eden do s1 přeživšího prostoru, nebo od s1 do s2.
Full GC nebo major GC provádí sběr neplatných dat v celé haldě. Full GC může také shromažďovat části, jako je metaprostor a přímá paměť, které lze vyčistit pouze úplným uvolňováním paměti.
Maximální velikost haldy ovlivňuje frekvenci menšího uvolňování paměti a plného uvolňování paměti. Maximální metaprostor a maximální velikost přímé paměti ovlivňují plné uvolňování paměti.
Pokud nastavíte maximální velikost haldy na nižší hodnotu, dochází ke sběru nečistot častěji, což aplikaci trochu zpomaluje, ale lépe omezuje využití paměti. Když nastavíte maximální velikost paměťové hromady na vyšší hodnotu, probíhá garbage collection méně často, což může způsobit větší riziko nedostatku paměti (OOM). Další informace najdete v části Typy problémů s nedostatkem paměti v dokumentu Problémy s restartováním aplikace způsobené nedostatkem paměti.
Metaprostor a přímou paměť lze uvolňovat pouze úplným GC. Pokud je metaprostor nebo přímá paměť plná, dojde k úplnému uvolňování paměti.
Konfigurace paměti Java
Následující části popisují důležité aspekty konfigurace paměti Java.
Kontejnerizace Java
Aplikace v Azure Spring Apps běží v kontejnerových prostředích. Další informace najdete v tématu Kontejnerizace aplikací v Javě.
Důležité možnosti prostředí JVM
Maximální velikost každé části paměti můžete nakonfigurovat pomocí možností prostředí JVM. Možnosti prostředí JVM můžete nastavit pomocí příkazů Azure CLI nebo webu Azure Portal. Další informace najdete v části Upravit konfigurace a opravit problémy nástroje pro řešení problémů s pamětí.
Následující seznam popisuje možnosti prostředí JVM:
Konfigurace velikosti haldy
-
-Xmsnastaví počáteční velikost haldy absolutní hodnotou. -
-Xmxnastaví maximální velikost haldy nastavením absolutní hodnoty. -
-XX:InitialRAMPercentagenastaví počáteční velikost haldy procentem z velikosti haldy / velikosti paměti aplikace. -
-XX:MaxRAMPercentagenastaví maximální velikost haldy na základě procenta z velikosti haldy nebo velikosti paměti aplikace.
-
Konfigurace přímé velikosti paměti
-
-XX:MaxDirectMemorySizenastaví maximální velikost přímé paměti absolutní hodnotou. Další informace naleznete v tématu MaxDirectMemorySize v dokumentaci Oracle.
-
Konfigurace velikosti metaprostoru
-
-XX:MaxMetaspaceSizenastaví maximální velikost metaprostoru absolutní hodnotou.
-
Výchozí maximální velikost paměti
Následující části popisují, jak jsou nastaveny výchozí maximální velikosti paměti.
Výchozí maximální velikost haldy
Azure Spring Apps nastaví výchozí maximální velikost paměti haldy na přibližně 50 –80 % paměti aplikace pro aplikace v Javě. Konkrétně Azure Spring Apps používá následující nastavení:
- Pokud paměť < aplikace 1 GB, bude výchozí maximální velikost haldy 50 % paměti aplikace.
- Pokud je paměť aplikace mezi 1 GB < a 2 GB <, bude výchozí maximální velikost heap prostoru 60 % paměti aplikace.
- Pokud paměť aplikace je mezi 2 GB < a 3 GB <, výchozí maximální velikost haldy bude 70 % paměti aplikace.
- Pokud 3 GB <= paměť aplikace, výchozí maximální velikost haldy bude 80 % paměti aplikace.
Výchozí maximální velikost přímé paměti
Pokud maximální velikost přímé paměti není nastavena pomocí možností JVM, JVM automaticky nastaví maximální přímou velikost paměti na hodnotu vrácenou modulem Runtime.getRuntime.maxMemory(). Tato hodnota se přibližně rovná maximální velikosti paměti haldy. Další informace naleznete v souboru JDK 8 VM.java.
Rozložení využití paměti
Velikost haldy má vliv na propustnost. V podstatě při konfiguraci můžete zachovat výchozí maximální velikost haldy, která ponechá přiměřenou paměť pro jiné části.
Velikost metaprostoru závisí na složitosti kódu, například počtu tříd.
Velikost přímé paměti závisí na propustnosti a použití knihoven třetích stran, jako je nio a gzip.
Následující seznam popisuje typickou ukázku rozložení paměti pro 2 GB aplikací. V tomto seznamu můžete nakonfigurovat nastavení velikosti paměti.
- Celková paměť (2048 M)
- Paměť haldy: Xmx je 1433,6M (70 % celkové paměti). Referenční hodnota denního využití paměti je 1200 M.
- Mladá generace
- Přeživší prostor (S0, S1)
- Eden space
- Stará generace
- Mladá generace
- Paměť mimo haldu
- Sledovaná část (sledovaná pomocí Spring Boot Actuator)
- Metaspace: Referenční hodnota denního využití je 50M–256M
- Mezipaměť kódu
- Komprimovaný prostor třídy
- Nepozorovaná část (nepozorovaná ovladačem Spring Boot): Referenční hodnota denního využití je 150M-250M.
- Zásobník vláken
- GC, vnitřní symbol a další
- Sledovaná část (sledovaná pomocí Spring Boot Actuator)
- Přímá paměť: Referenční hodnota denního využití je 10M–200M.
Následující diagram znázorňuje stejné informace. Šedá čísla jsou referenčními hodnotami denního využití paměti.
Celkově byste při konfiguraci maximální velikosti paměti měli zvážit využití každé části paměti a součet všech maximálních velikostí by neměl překročit celkovou dostupnou paměť.
Java OOM
OOM znamená, že aplikace není v paměti. Existují dva různé koncepty: kontejner OOM a OOM JVM. Další informace najdete v tématu Problémy s restartováním aplikace způsobené problémy s nedostatkem paměti.