OutOfMemoryError: GC Overhead Limit Exceeded

1. Översikt

Enkelt uttryckt tar JVM hand om att frigöra minne när objekt inte längre används; denna process kallas Garbage Collection (GC).

Den GC Overhead Överskrider begr fel är en från familjen av java.lang.OutOfMemoryError och är en indikation på en resurs (minne) utmattning.

I den här snabba artikeln tittar vi på vad som orsakar java.lang.OutOfMemoryError: GC Overhead Limit Exceeded error och hur det kan lösas.

2. GC-overheadgräns överskred fel

OutOfMemoryError är en underklass av java.lang.VirtualMachineError ; det kastas av JVM när det stöter på ett problem relaterat till resursanvändning. Mer specifikt inträffar felet när JVM tillbringade för mycket tid på att utföra skräpsamling och bara kunde återta mycket lite högutrymme.

Enligt Java-dokument är JVM som standard konfigurerad för att kasta detta fel om Java-processen tillbringar mer än 98% av sin tid på att göra GC och när endast mindre än 2% av högen återställs i varje körning. Med andra ord betyder det att vår applikation har tömt nästan allt tillgängligt minne och Garbage Collector har spenderat för mycket tid på att försöka rengöra det och misslyckades upprepade gånger.

I den här situationen upplever användarna extremt långsam applikation. Vissa operationer, som vanligtvis slutförs på millisekunder, tar längre tid att slutföra. Detta beror på att processorn använder hela sin kapacitet för skräpsamling och därmed inte kan utföra några andra uppgifter.

3. Fel i aktion

Låt oss titta på en kod som kastar java.lang.OutOfMemoryError: GC Overhead Limit Exceeded.

Vi kan uppnå det, till exempel genom att lägga till nyckel-värdepar i en obestämd slinga:

public class OutOfMemoryGCLimitExceed { public static void addRandomDataToMap() { Map dataMap = new HashMap(); Random r = new Random(); while (true) { dataMap.put(r.nextInt(), String.valueOf(r.nextInt())); } } }

När den här metoden åberopas, med JVM-argumenten som -Xmx100m -XX: + UseParallelGC ( Java-heapstorlek är inställd på 100MB och GC-algoritmen är ParallelGC), får vi ett java.lang.OutOfMemoryError: GC Overhead Limit Exceeded error. För att få en bättre förståelse för olika algoritmer för Garbage Collection kan vi läsa Oracle's Java Garbage Collection Basics tutorial.

Vi får ett java.lang.OutOfMemoryError: GC Overhead Limit överskred fel mycket snabbt genom att köra följande kommando från projektets rot:

mvn exec:exec

Det bör också noteras att vi i vissa situationer kan stöta på ett heap space-fel innan vi stöter på GC Overhead Limit Exceeded- felet.

4. Lösning av GC-overheadgräns överskridit fel

Den perfekta lösningen är att hitta det bakomliggande problemet med applikationen genom att undersöka koden för eventuella minnesläckor.

Följande frågor måste behandlas:

  • Vilka är objekten i applikationen som upptar stora delar av högen?
  • I vilka delar av källkoden tilldelas dessa objekt?

Vi kan också använda automatiserade grafiska verktyg som JConsole som hjälper till att upptäcka prestandaproblem i koden inklusive java.lang.OutOfMemoryErrors.

Den sista utvägen skulle vara att öka hopstorleken genom att ändra JVM-lanseringskonfigurationen. Till exempel ger detta 1 GB högutrymme för Java-applikationen:

java -Xmx1024m com.xyz.TheClassName

Detta löser dock inte problemet om det finns minnesläckor i den faktiska applikationskoden. Istället skjuter vi bara upp felet. Därför är det mer lämpligt att ompröva applikationens minnesanvändning noggrant.

5. Sammanfattning

I denna handledning undersökte vi java.lang.OutOfMemoryError: GC Overhead Limit Exceeded och orsakerna bakom den.

Som alltid kan källkoden relaterad till den här artikeln hittas på GitHub.