OutOfMemoryError: Bol prekročený režijný limit GC
1. Prehľad
Jednoducho povedané, JVM sa postará o uvoľnenie pamäte, keď sa objekty už nepoužívajú; tento proces sa nazýva Garbage Collection (GC).
The Bol prekročený režijný limit GC chyba je jedna z rodiny java.lang.OutOfMemoryError a je indikáciou vyčerpania zdroja (pamäte).
V tomto rýchlom článku sa pozrieme na to, čo spôsobuje java.lang.OutOfMemoryError: Bol prekročený režijný limit GC chyba a ako sa to da riesit.
2. Bola prekročená chyba režijného limitu GC
OutOfMemoryError je podtrieda java.lang.VirtualMachineError; vyhodí ho JVM, keď narazí na problém súvisiaci s využívaním zdrojov. Konkrétnejšie, chyba nastane, keď JVM strávil príliš veľa času vykonávaním Zberu odpadu a dokázal získať späť len veľmi málo haldy priestoru.
Podľa dokumentov Java je server JVM štandardne nakonfigurovaný tak, aby túto chybu vyhodil, ak proces Java trávi viac ako 98% času vykonávaním GC a keď sa v každom spustení obnovia iba menej ako 2% haldy. Inými slovami to znamená, že naša aplikácia vyčerpala takmer všetku dostupnú pamäť a program Garbage Collector strávil príliš veľa času pokusom o jej čistenie a opakovane zlyhával.
V tejto situácii používatelia zaznamenávajú extrémnu pomalosť aplikácie. Niektoré operácie, ktoré sa zvyčajne dokončia v milisekundách, trvajú viac času. Je to tak preto, lebo CPU využíva celú svoju kapacitu na zhromažďovanie odpadu, a preto nemôže vykonávať žiadne ďalšie úlohy.
3. Chyba v akcii
Pozrime sa na kúsok kódu, ktorý hodí java.lang.OutOfMemoryError: Bol prekročený režijný limit GC.
To môžeme dosiahnuť napríklad pridaním párov kľúč - hodnota do neukončenej slučky:
verejná trieda OutOfMemoryGCLimitExceed {public static void addRandomDataToMap () {Map dataMap = new HashMap (); Náhodné r = nové Náhodné (); while (true) {dataMap.put (r.nextInt (), String.valueOf (r.nextInt ())); }}}
Keď je táto metóda vyvolaná, s argumentmi JVM ako -Xmx100m -XX: + UseParallelGC (Veľkosť haldy Java je nastavená na 100 MB a algoritmus GC je ParallelGC), dostaneme a java.lang.OutOfMemoryError: Bol prekročený režijný limit GC chyba. Aby sme lepšie porozumeli rozličným algoritmom Garbage Collection Algorithms, môžeme si pozrieť výukový program Oracle Java Garbage Collection Basics.
Dostaneme a java.lang.OutOfMemoryError: Bol prekročený režijný limit GC chyba veľmi rýchlo spustením nasledujúceho príkazu z koreňa projektu:
mvn exec: exec
Je tiež potrebné poznamenať, že v niektorých situáciách by sme sa mohli stretnúť s chybou haldy priestoru skôr, ako narazíme na Bol prekročený režijný limit GC chyba.
4. Riešenie prekročenej chyby režijného limitu GC
Ideálnym riešením je nájsť základný problém s aplikáciou preskúmaním kódu kvôli prípadným únikom pamäte.
Je potrebné zodpovedať nasledujúce otázky:
- Čo sú objekty v aplikácii, ktoré zaberajú veľké časti haldy?
- V ktorých častiach zdrojového kódu sa tieto objekty prideľujú?
Môžeme tiež použiť automatizované grafické nástroje, ako je JConsole, ktorá pomáha zisťovať problémy s výkonom v kóde vrátane java.lang.OutOfMemoryErrors.
Posledným riešením by bolo zväčšiť veľkosť haldy zmenou konfigurácie spustenia JVM. Napríklad to dá 1GB haldy priestoru pre aplikáciu Java:
java -Xmx1024m com.xyz.TheClassName
To však problém nevyrieši, ak v skutočnom kóde aplikácie dôjde k úniku pamäte. Namiesto toho chybu iba odložíme. Preto je vhodnejšie dôkladne prehodnotiť využitie pamäte aplikáciou.
5. Záver
V tomto návode sme preskúmali java.lang.OutOfMemoryError: Bol prekročený režijný limit GC a dôvody za tým.
Zdrojový kód súvisiaci s týmto článkom nájdete ako vždy na serveri GitHub.