OutOfMemoryError: GC-Overhead-Limit überschritten

1. Übersicht

Einfach ausgedrückt, sorgt die JVM dafür, dass Speicher freigegeben wird, wenn Objekte nicht mehr verwendet werden. Dieser Vorgang wird als Garbage Collection (GC) bezeichnet.

Der GC Overhead Limit Exceeded- Fehler stammt aus der Familie von java.lang.OutOfMemoryError und ist ein Hinweis auf eine Ressourcen- (Speicher-) Erschöpfung.

In diesem kurzen Artikel werden wir untersuchen, was den Fehler java.lang.OutOfMemoryError: GC Overhead Limit Exceeded verursacht und wie er behoben werden kann.

2. GC-Overhead-Limit überschritten Fehler

OutOfMemoryError ist eine Unterklasse von java.lang.VirtualMachineError ; Es wird von der JVM ausgelöst, wenn ein Problem im Zusammenhang mit der Verwendung von Ressourcen auftritt. Insbesondere tritt der Fehler auf, wenn die JVM zu viel Zeit mit der Garbage Collection verbracht hat und nur sehr wenig Heap-Speicherplatz zurückgewinnen konnte.

Laut Java-Dokumenten ist die JVM standardmäßig so konfiguriert, dass dieser Fehler ausgelöst wird, wenn der Java-Prozess mehr als 98% seiner Zeit mit GC verbringt und nur weniger als 2% des Heaps in jedem Lauf wiederhergestellt werden. Mit anderen Worten bedeutet dies, dass unsere Anwendung fast den gesamten verfügbaren Speicher erschöpft hat und der Garbage Collector zu viel Zeit damit verbracht hat, ihn zu bereinigen, und wiederholt fehlgeschlagen ist.

In dieser Situation tritt bei Benutzern eine extreme Langsamkeit der Anwendung auf. Bestimmte Vorgänge, die normalerweise in Millisekunden ausgeführt werden, benötigen mehr Zeit. Dies liegt daran, dass die CPU ihre gesamte Kapazität für die Speicherbereinigung nutzt und daher keine anderen Aufgaben ausführen kann.

3. Fehler in Aktion

Schauen wir uns einen Code an, der java.lang.OutOfMemoryError auslöst: GC Overhead Limit Exceeded.

Dies können wir beispielsweise erreichen, indem wir Schlüssel-Wert-Paare in einer nicht abgeschlossenen Schleife hinzufügen:

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())); } } }

Wenn diese Methode mit den JVM-Argumenten -Xmx100m -XX: + UseParallelGC aufgerufen wird ( Java-Heap-Größe ist auf 100 MB festgelegt und der GC-Algorithmus ist ParallelGC), wird der Fehler java.lang.OutOfMemoryError: GC Overhead Limit Exceeded angezeigt . Um ein besseres Verständnis der verschiedenen Garbage Collection-Algorithmen zu erhalten, können Sie das Tutorial zu den Java Garbage Collection-Grundlagen von Oracle lesen.

Wir erhalten einen java.lang.OutOfMemoryError: GC Overhead Limit Der Fehler wurde sehr schnell überschritten , indem der folgende Befehl im Stammverzeichnis des Projekts ausgeführt wurde:

mvn exec:exec

Es sollte auch beachtet werden, dass in einigen Situationen möglicherweise ein Heap-Space-Fehler auftritt, bevor der Fehler GC Overhead Limit Exceeded auftritt .

4. Lösen des GC Overhead Limit Exceeded Error

Die ideale Lösung besteht darin, das zugrunde liegende Problem mit der Anwendung zu finden, indem der Code auf Speicherlecks untersucht wird.

Folgende Fragen müssen beantwortet werden:

  • Welche Objekte in der Anwendung belegen große Teile des Heaps?
  • In welchen Teilen des Quellcodes werden diese Objekte zugeordnet?

Wir können auch automatisierte grafische Tools wie JConsole verwenden, mit denen Leistungsprobleme im Code erkannt werden können, einschließlich java.lang.OutOfMemoryErrors.

Der letzte Ausweg wäre, die Größe des Heapspeichers durch Ändern der JVM-Startkonfiguration zu erhöhen. Dies ergibt beispielsweise 1 GB Heapspeicher für die Java-Anwendung:

java -Xmx1024m com.xyz.TheClassName

Dies löst das Problem jedoch nicht, wenn der tatsächliche Anwendungscode Speicherlecks aufweist. Stattdessen werden wir den Fehler einfach verschieben. Daher ist es ratsamer, die Speichernutzung der Anwendung gründlich zu überprüfen.

5. Schlussfolgerung

In diesem Tutorial haben wir den java.lang.OutOfMemoryError: GC Overhead Limit Exceeded und die Gründe dafür untersucht.

Wie immer finden Sie den Quellcode zu diesem Artikel auf GitHub.