956 Stimmen

Fehler java.lang.OutOfMemoryError: GC-Overhead-Grenze überschritten

Ich erhalte diese Fehlermeldung, wenn ich meine JUnit Tests:

java.lang.OutOfMemoryError: GC overhead limit exceeded

Ich weiß, was ein OutOfMemoryError ist, aber was bedeutet die GC-Overhead-Grenze? Wie kann ich das lösen?

18 Stimmen

Das klingt sehr interessant. Ich würde mich freuen, wenn jemand einen Code posten könnte, der dies erzeugt.

2 Stimmen

Ich habe einfach das Problem gefunden, das zu einem zu hohen Speicherverbrauch in der Nähe der Grenze des Heaps führte. Eine einfache Lösung könnte sein, der Java-Engine einfach etwas mehr Heap-Speicher zu geben (-Xmx), aber das hilft nur, wenn die Anwendung genau so viel Speicher benötigt, wie das Heap-Limit vorher gesetzt war.

0 Stimmen

862voto

Joachim Sauer Punkte 290477

Diese Meldung bedeutet, dass der Garbage Collector aus irgendeinem Grund übermäßig viel Zeit benötigt (standardmäßig 98 % der gesamten CPU-Zeit des Prozesses) und bei jedem Durchlauf nur sehr wenig Speicher zurückgewinnt (standardmäßig 2 % des Heaps).

Das bedeutet, dass Ihr Programm keinen Fortschritt mehr macht und die ganze Zeit nur noch mit der Garbage Collection beschäftigt ist.

Um zu verhindern, dass Ihre Anwendung CPU-Zeit in Anspruch nimmt, ohne etwas zu tun, wirft die JVM diese Error damit Sie eine Chance haben, das Problem zu diagnostizieren.

Die seltenen Fälle, in denen ich dies gesehen habe, ist, wo einige Code Tonnen von temporären Objekten und Tonnen von schwach referenzierten Objekten in einer bereits sehr Speicher-begrenzten Umgebung erstellt wurde.

Sehen Sie sich den Java GC tuning guide an, der für verschiedene Java-Versionen verfügbar ist und Abschnitte zu diesem speziellen Problem enthält:

13 Stimmen

Wäre es richtig, Ihre Antwort wie folgt zusammenzufassen? "Es ist genau wie ein 'Out of Java Heap space'-Fehler. Geben Sie ihm mit -Xmx mehr Speicher." ?

70 Stimmen

@Tim: Nein, das wäre nicht korrekt. Auch wenn man ihm mehr Speicher gibt könnte Wenn Sie das Problem reduzieren wollen, sollten Sie sich auch Ihren Code ansehen und herausfinden, warum er diese Menge an Speicherplatz produziert und warum Ihr Code knapp unter der "Out of Memory"-Marke vorbeischrammt. Das ist oft ein Zeichen für fehlerhaften Code.

11 Stimmen

Danke, es scheint, dass Oracle nicht wirklich gut in der Datenmigration ist, sie haben die Verbindung unterbrochen.

249voto

dave Punkte 11113

Zitat aus dem Artikel von Oracle "Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning" :

Übermäßige GC-Zeit und OutOfMemoryError

Der parallele Kollektor gibt einen OutOfMemoryError aus, wenn zu viel Zeit mit der Garbage Collection verbracht wird: Wenn mehr als 98% der Gesamtzeit mit der Garbage Collection verbracht wird und weniger als 2% des Heaps wiederhergestellt werden, wird ein OutOfMemoryError ausgegeben. Mit dieser Funktion soll verhindert werden, dass Anwendungen über einen längeren Zeitraum laufen, aber keine oder nur geringe Fortschritte machen, weil der Heap zu klein ist. Falls erforderlich, kann diese Funktion durch Hinzufügen der Option -XX:-UseGCOverheadLimit in die Befehlszeile.

EDIT: Sieht so aus, als könnte jemand schneller tippen als ich :)

94 Stimmen

"Sie können dies ausschalten...", aber der OP sollte dies höchstwahrscheinlich nicht tun.

2 Stimmen

Können Sie mir den Unterschied zwischen "-XX" und "-Xmx" erklären? Ich konnte sie auch mit der Option "-Xmx" ausschalten.

23 Stimmen

Ich antworte hier auf einen sehr alten Kommentar, aber... @Bart Der -XX: am Anfang mehrerer Befehlszeilenoptionen ist eine Art Flagge, die anzeigt, dass diese Option in hohem Maße VM-spezifisch und instabil ist (und sich in zukünftigen Versionen ohne Ankündigung ändern kann). In jedem Fall ist die -XX:-UseGCOverheadLimit Flag weist die VM an, die Überprüfung des GC-Overhead-Limits zu deaktivieren (tatsächlich "auszuschalten"), während Ihr -Xmx hat lediglich den Haufen vergrößert. Im letzteren Fall war die Überprüfung des GC-Overheads immer noch läuft Es hört sich so an, als ob ein größerer Heap die GC-Thrashing-Probleme gelöst hätte. in Ihrem Fall (dies ist nicht immer hilfreich).

109voto

Vitalii Fedorenko Punkte 103468

Wenn Sie sicher sind, dass es keine Speicherlecks in Ihrem Programm, versuchen Sie es:

  1. Erhöhen Sie die Heap-Größe, zum Beispiel -Xmx1g .
  2. Aktivieren Sie den Kollektor für gleichzeitige niedrige Pausen -XX:+UseConcMarkSweepGC .
  3. Verwenden Sie vorhandene Objekte nach Möglichkeit wieder, um Speicherplatz zu sparen.

Erforderlichenfalls kann die Grenzwertprüfung kann durch Hinzufügen der folgenden Option deaktiviert werden -XX:-UseGCOverheadLimit in die Befehlszeile.

11 Stimmen

I

57voto

Mike Punkte 1350

Normalerweise ist es der Code. Hier ist ein einfaches Beispiel:

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

Verwendung von Java 1.6.0_24-b07 auf einem Windows 7 32 bit.

java -Xloggc:gc.log GarbageCollector

Dann schauen Sie sich gc.log

  • 444 Mal mit der BAD-Methode ausgelöst
  • 666 Mal mit der WORSE-Methode ausgelöst
  • 354 Mal mit der BETTER-Methode ausgelöst

Zugegeben, das ist nicht der beste Test oder das beste Design, aber wenn man mit einer Situation konfrontiert ist, in der man keine andere Wahl hat, als eine solche Schleife zu implementieren, oder wenn man mit bestehendem Code zu tun hat, der sich schlecht verhält, kann die Entscheidung, Objekte wiederzuverwenden, anstatt neue zu erstellen, die Anzahl der Fälle reduzieren, in denen der Garbage Collector in die Quere kommt.

14 Stimmen

Bitte klären Sie: Wenn Sie sagen, "n-mal ausgelöst", bedeutet das, dass eine reguläre GC n-mal passiert, oder dass der "GC-Overhead-Limit überschritten" Fehler von der OP berichtet n-mal passiert?

0 Stimmen

Ich testete gerade jetzt mit Java 1.8.0_91 und bekam nie einen Fehler/Ausnahme, und die "Triggered n-mal" wurde von Zählen der Anzahl der Zeilen in der gc.log Datei. Meine Tests zeigen insgesamt viel weniger Zeiten, aber die wenigsten "Auslöser"-Zeiten für BETTER, und jetzt ist BAD "schlimmer" als WORST. Meine Zählungen: SCHLECHT: 26, SCHLECHTER: 22, BESSER 21.

0 Stimmen

Ich habe gerade eine "WORST_YET"-Modifikation hinzugefügt, in der ich die List<Double> list im äußere Schleife 代わりに avant die äußere Schleife, und Triggered 39 Garbage Collections.

39voto

Ravindra babu Punkte 45577

Ursache für den Fehler nach der Java [8] Plattform, Standard Edition Anleitung zur Fehlerbehebung (Hervorhebung und Zeilenumbrüche hinzugefügt)

[...] "GC overhead limit exceeded" zeigt an, dass der Garbage Collector ständig läuft und das Java-Programm nur sehr langsam vorankommt.

Nach einer Garbage Collection, wenn die Java-Prozesse verbringen mehr als 98% ihrer Zeit mit der Garbage Collection und wenn es weniger als 2% des Heaps wiederherstellt und dies die letzten 5 (zur Kompilierzeit konstanten) aufeinanderfolgenden Garbage Collections getan hat, dann wird ein java.lang.OutOfMemoryError geworfen wird. [...]

  1. Vergrößerung des Heaps wenn der aktuelle Heap nicht ausreicht.
  2. Wenn Sie diesen Fehler immer noch erhalten, nachdem Sie den Heap-Speicher erhöht haben, verwenden Sie memory Profilierungswerkzeuge wie MAT (Werkzeug zur Speicheranalyse), Visuelle VM usw. und beheben Speicherlecks.
  3. Aktualisieren Sie die JDK-Version auf die neueste Version (1.8.x) oder mindestens 1.7.x und verwenden Sie den G1GC-Algorithmus. . Das Durchsatzziel für den G1 GC liegt bei 90 Prozent Anwendungszeit und 10 Prozent Garbage-Collection-Zeit
  4. Neben dem Setzen von Heap-Speicher mit - Xms1g -Xmx2g , versuchen

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m  
    -XX:ParallelGCThreads=n -XX:ConcGCThreads=n

Sehen Sie sich einige weitere Fragen zu G1GC an

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X