Fehler java.lang.OutOfMemoryError: GC Overhead Limit überschritten

Ich erhalte diese Fehlermeldung, während ich meine JUnit-Tests ausführe:

java.lang.OutOfMemoryError: GC overhead limit exceeded 

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

   

Diese Nachricht bedeutet, dass der Garbage Collector aus irgendeinem Grund zu viel Zeit in Anspruch nimmt (standardmäßig 98% der gesamten CPU-Zeit des processes) und in jedem Lauf nur sehr wenig Speicher wiederherstellt (standardmäßig 2% des Heapspeichers).

Dies bedeutet effektiv, dass Ihr Programm keine Fortschritte mehr macht und immer nur die Garbage-Collection ausführt.

Um zu verhindern, dass Ihre Anwendung CPU-Zeit in Anspruch nimmt, ohne dass etwas ausgeführt wird, triggers die JVM diesen Error sodass Sie eine Chance haben, das Problem zu diagnostizieren.

Die seltenen Fälle, in denen ich dies beobachtet habe, sind Fälle, in denen Code in einer Umgebung mit sehr eingeschränkten Speichermöglichkeiten Tonnen von temporären Objekten und Tonnen von schwach referenzierten Objekten erzeugte.

In diesem Artikel finden Sie Details (speziell diesen Teil ).

Der GC gibt diese Ausnahme aus, wenn zu viel Zeit in der Garbage Collection für zu wenig Return verbraucht wird, z. 98% der CPU-Zeit werden für GC verbraucht und weniger als 2% des Heaps werden wiederhergestellt.

Diese function soll verhindern, dass Anwendungen über einen längeren Zeitraum ausgeführt werden, während der Heap zu klein ist.

Sie können dies mit der Befehlszeilenoption -XX:-UseGCOverheadLimit

Mehr Infos hier

EDIT: sieht aus wie jemand schneller tippen kann als ich 🙂

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

  1. -Xmx1g die Größe des -Xmx1g , z. B. -Xmx1g .
  2. Aktivieren Sie den gleichzeitigen Kollektor -XX:+UseConcMarkSweepGC niedrige Pausen -XX:+UseConcMarkSweepGC .
  3. Wenn möglich, können Sie vorhandene Objekte wiederverwenden, um Speicherplatz zu sparen.

Bei Bedarf kann die Grenzwertprüfung durch Hinzufügen der Option -XX:-UseGCOverheadLimit zur Befehlszeile deaktiviert werden.

Es ist normalerweise 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 list = new ArrayList(); for (int outer = 0; outer < 10000; outer++) { // list = new ArrayList(10000); // BAD // list = new ArrayList(); // 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"); } } 

Verwenden von Java 1.6.0_24-b07 Auf einem Windows7 32 Bit.

java -Xloggc: gc.log GarbageCollector

Dann schau dir gc.log an

  • 444 Mal mit der BAD-Methode ausgetriggers
  • 666-mal mit der WORSE-Methode ausgetriggers
  • 354 Mal mit der BETTER-Methode ausgetriggers

Dies ist zwar nicht der beste Test oder das beste Design, aber in Situationen, in denen Sie keine andere Wahl haben, als eine solche Schleife zu implementieren oder sich mit bereits schlecht funktionierendem Code zu befassen, kann die Wiederverwendung von Objekten reduziert werden wie oft der Müllsammler in die Quere kommt ...

Erhöhen Sie einfach die Größe des Heapspeichers, indem Sie diese Option aktivieren

Ausführen → Run-Konfigurationen → Argumente → VM-Argumente

 -Xms1024M -Xmx2048M 

Xms – für minimale Grenze

Xmx – für maximale Begrenzung

Ursache für den Fehler

GC overhead limit exceeded “zeigt an, dass der Garbage Collector ständig ausgeführt wird und das Java-Programm einen sehr langsamen Fortschritt macht.

Nach einer Garbage-Collection, wenn der Java-process mehr als etwa 98% seiner Zeit damit zubringt, Garbage Collection durchzuführen und wenn er weniger als 2% des Heapspeichers wiederherstellt und bislang die letzten 5 (Kompilierzeitkonstante) aufeinanderfolgenden Garbage-Vorgänge ausgeführt hat Sammlungen, dann wird ein java.lang.OutOfMemoryError geworfen

  1. Erhöhen Sie die Heap-Größe, wenn der aktuelle Heap nicht ausreicht.
  2. Wenn dieser Fehler nach dem Erhöhen des Heapspeichers immer noch auftritt, verwenden Sie Speicherprofilerstellungs- Tools wie MAT (Speicheranalysetool), Visual VM usw. und beheben Sie 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 beträgt 90 Prozent Anwendungszeit und 10 Prozent Speicherbereinigung
  4. Xms1g -Xmx2g neben dem Festlegen Xms1g -Xmx2g mit – Xms1g -Xmx2g

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

Werfen Sie einen Blick auf weitere verwandte Fragen zu G1GC

Java 7 (JDK 7) Speicherbereinigung und Dokumentation auf G1

Java G1 Müllsammlung in der Produktion

Oracle Technetwork-Artikel für GC-Feinabstimmung

Für mich haben folgende Schritte funktioniert:

  1. Öffnen Sie die Datei eclipse.ini
  2. Veränderung

     -Xms40m -Xmx512m 

    zu

     -Xms512m -Xmx1024m 
  3. Starte Eclipse neu

Siehe hier

Versuche dies

Öffnen Sie die Datei build.gradle

  android { dexOptions { javaMaxHeapSize = "4g" } } 

Das Folgende funktionierte für mich. Fügen Sie einfach das folgende Snippet hinzu:

 android { compileSdkVersion 25 buildToolsVersion '25.0.1' defaultConfig { applicationId "yourpackage" minSdkVersion 10 targetSdkVersion 25 versionCode 1 versionName "1.0" multiDexEnabled true } dexOptions { javaMaxHeapSize "4g" } } 

Erhöhen Sie javaMaxHeapsize in Ihrer Datei build.gradle (Module: app)

 dexOptions { javaMaxHeapSize "1g" } 

(Fügen Sie diese Zeile in Großbuchstaben hinzu)

  dexOptions { javaMaxHeapSize "4g" } 

Sie müssen die Speichergröße in JDeveloper auf setDomainEnv.cmd erhöhen .

 set WLS_HOME=%WL_HOME%\server set XMS_SUN_64BIT=**256** set XMS_SUN_32BIT=**256** set XMX_SUN_64BIT=**3072** set XMX_SUN_32BIT=**3072** set XMS_JROCKIT_64BIT=**256** set XMS_JROCKIT_32BIT=**256** set XMX_JROCKIT_64BIT=**1024** set XMX_JROCKIT_32BIT=**1024** if "%JAVA_VENDOR%"=="Sun" ( set WLS_MEM_ARGS_64BIT=**-Xms256m -Xmx512m** set WLS_MEM_ARGS_32BIT=**-Xms256m -Xmx512m** ) else ( set WLS_MEM_ARGS_64BIT=**-Xms512m -Xmx512m** set WLS_MEM_ARGS_32BIT=**-Xms512m -Xmx512m** ) 

und

 set MEM_PERM_SIZE_64BIT=-XX:PermSize=**256m** set MEM_PERM_SIZE_32BIT=-XX:PermSize=**256m** if "%JAVA_USE_64BIT%"=="true" ( set MEM_PERM_SIZE=%MEM_PERM_SIZE_64BIT% ) else ( set MEM_PERM_SIZE=%MEM_PERM_SIZE_32BIT% ) set MEM_MAX_PERM_SIZE_64BIT=-XX:MaxPermSize=**1024m** set MEM_MAX_PERM_SIZE_32BIT=-XX:MaxPermSize=**1024m** 

Ich arbeite in Android Studio und habe diesen Fehler bei der Erstellung eines signierten APKs zur Veröffentlichung festgestellt. Ich war in der Lage, eine Debug-APK ohne Probleme zu erstellen und zu testen, aber sobald ich eine Release-APK erstellen wollte, würde der Build-process minutenlang laufen und dann schließlich mit dem “Error java.lang.OutOfMemoryError: GC Overhead Limit überschritten “. Ich habe die Heap-Größen sowohl für den VM- als auch für den Android-DEX-Compiler erhöht, aber das Problem ist weiterhin aufgetreten. Endlich, nach vielen Stunden und Tassen Kaffee, stellte sich heraus, dass das Problem in meiner ‘build.gradle’-Datei auf App-Ebene lag – ich hatte den’ minifyEnabled’-Parameter für den Release-Build-Typ auf ‘false’ gesetzt und folglich Proguard-Sachen ausgeführt auf Code, der den Code-Schrumpfungsprozess nicht durchlaufen hat (siehe https://developer.android.com/studio/build/shrink-code.html ). Ich habe den Parameter ‘minifyEnabled’ in ‘true’ geändert und den Release-Build wie einen Traum ausgeführt 🙂

Kurz gesagt, ich musste meine “build.gradle” -Datei auf App-Ebene von: // …

 buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.sign_config_release } debug { debuggable true signingConfig signingConfigs.sign_config_debug } } //... 

zu

  //... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.sign_config_release } debug { debuggable true signingConfig signingConfigs.sign_config_debug } } //... 

In Netbeans kann es hilfreich sein, eine maximale Heap-Größe zu entcasting. Gehe zu Run => Setze Projektkonfiguration => Anpassen . Im Run des Pop-up-Fensters gehen Sie zu VM Option , füllen Sie -Xms2048m -Xmx2048m . Es könnte das Problem mit der Größe des Heapspeichers lösen.

Befolgen Sie die folgenden statementen, um die Größe des Heapspeichers in IntelliJ IDEA zu erhöhen. Es hat für mich funktioniert.

Für Windows Benutzer

Wechseln Sie zu dem Speicherort, an dem die IDE installiert ist, und suchen Sie nach folgenden Objekten.

 idea64.exe.vmoptions 

Bearbeiten Sie die Datei und fügen Sie Folgendes hinzu.

 -Xms512m -Xmx2024m -XX:MaxPermSize=700m -XX:ReservedCodeCacheSize=480m 

Das ist es !!