Frage

ich diese Fehlermeldung erhalten, wie ich meine JUnit-Tests ausführen:

java.lang.OutOfMemoryError: GC overhead limit exceeded

Ich weiß, was ein OutOfMemoryError ist, aber was bedeutet GC Obergrenze bedeuten? Wie kann ich dieses Problem lösen?

War es hilfreich?

Lösung

Diese Meldung bedeutet, dass aus irgendeinem Grund der Garbage Collector eine übermäßige Menge an Zeit nimmt (standardmäßig 98% aller CPU-Zeit des Prozesses) und erholt sich nur sehr wenig Speicher in jedem Lauf (standardmäßig 2% des Haufens) .

Dies effektiv bedeutet, dass Ihr Programm Fortschritte nicht mehr zu tun und ist damit beschäftigt zu jeder Zeit nur die Garbage Collection ausgeführt wird.

Ihre Anwendung zu verhindern, dass die CPU-Zeit aufzusaugen, ohne etwas zu erledigen, wirft die JVM diese Error so dass Sie eine Chance von der Diagnose des Problems haben.

Die seltenen Fälle, in denen ich das gesehen habe, geschehen ist, wo einige Code wurde Tonnen temporäre Objekte und Tonnen von schwach-referenzierte Objekte in einem bereits sehr speicher eingeschränkten Umgebung zu schaffen.

Sehen Sie sich diesem Artikel für Details (insbesondere dieser Teil ) .

Andere Tipps

Die GC wirft diese Ausnahme, wenn zu viel Zeit in der Garbage-Collection zu wenig Rückkehr ausgegeben wird, zum Beispiel. 98% der CPU-Zeit verbringt auf GC und weniger als 2% der Halde zurückgewonnen wird.

Diese Funktion ausgelegt ist, Anwendungen zu verhindern, für einen längeren Zeitraum starten, während wenig zu machen oder gar keine Fortschritte, weil die Halde zu klein ist.

Sie können diese drehen sich mit der Kommandozeilenoption aus -XX:-UseGCOverheadLimit

Weitere Informationen hier

EDIT: sieht aus wie jemand schneller als ich geben kann:)

Wenn Sie sich sicher sind, gibt es keine Speicherlecks in Ihrem Programm , versuchen zu:

  1. Erhöhen Sie die Speichergröße, zum Beispiel -Xmx1g.
  2. Aktivieren Sie die gleichzeitige niedrigen Pause Kollektor -XX:+UseConcMarkSweepGC.
  3. Reuse Objekte vorhanden ist, wenn möglich, etwas Speicher zu speichern.

Falls nötig, die Limitprüfung kann durch Hinzufügen der Option -XX:-UseGCOverheadLimit an die Befehlszeile deaktiviert werden.

Es ist in der Regel 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");
    }
}

Mit Java 1.6.0_24-b07 Auf einem Windows7 32 Bit.

java -Xloggc: gc.log GarbageCollector

Schauen Sie sich gc.log

  • Triggered 444 mal BAD Methode mit
  • Ausgelöst 666 mal WORSE Methode mit
  • Triggered 354 mal mit BETTER Methode

Nun gewährt, ist dies nicht der beste Test oder das beste Design, aber wenn sie mit einer Situation konfrontiert, wo man keine andere Wahl, aber eine solche Schleife implementieren oder wenn sie mit bestehenden Code zu tun, dass sich schlecht benimmt Wahl, um die Wiederverwendung Objekte anstatt neue zu schaffen, diejenigen, kann die Anzahl der Male der Garbage Collector in die Quere kommt ...

reduzieren

Ursache für die Fehler

  

GC Obergrenze überschritten“zeigt an, dass der Garbage Collector die ganze Zeit läuft und Java-Programm schreitet sehr langsam voran.

Nach einer Garbage Collection, wenn die Java-Prozess mehr ausgibt als etwa 98% seiner Zeit Garbage Collection zu tun und wenn sie erholt sich weniger als 2% des Haufens und wurde dabei so weit die letzten 5 (Kompilierung konstant) aufeinander folgenden Garbage Collection, dann ein java.lang.OutOfMemoryError wird geworfen

  1. Erhöhen Sie die Heap-Größe , wenn die aktuelle Heap ist nicht genug.
  2. Wenn Sie diesen Fehler weiterhin erhalten, nachdem steigenden Heap-Speicher, verwenden Speicher Profilierwerkzeuge wie MAT (Memory Analyzer-Tool), von Visual VM etc und fix Speicherlecks.
  3. Upgrade JDK-Version auf die neueste Version (1.8.x) oder zumindest 1.7.x und Verwendung G1GC Algorithmus. . Das Durchsatz Ziel für das G1 GC beträgt 90 Prozent Anwendungszeit und 10 Prozent der Garbage Collection Zeit
  4. Neben mit -Xms1g -Xmx2g Heap-Speicher Einstellung, versuchen

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

Werfen Sie einen Blick auf einige weitere Fragen in Bezug auf G1GC

Java 7 (JDK 7) Garbage Collection und Dokumentation auf G1

Java G1 Garbage Collection in der Produktion

Oracle TechNetwork Artikel für GC Feinabstimmung

Erhöhen Sie einfach die Heap-Größe ein wenig von dieser Einstellung in

Ausführen → Ausführen Konfigurationen → Argumente → VM Argumente

-Xms1024M -Xmx2048M

Xms - für Mindestgrenze

Xmx - für maximale Grenze

Für mich sind die folgenden Schritte bearbeitet:

  1. Öffnen Sie die Datei eclipse.ini
  2. Ändern

    -Xms40m
    -Xmx512m
    

    -Xms512m
    -Xmx1024m
    
  3. Starten Sie Eclipse-

hier sehen

Versuchen Sie, diese

Öffnen Sie die Datei build.gradle

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

Im Folgenden arbeitete für mich. Fügen Sie einfach den folgenden Ausschnitt:

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öht JavaMaxHeapSize in Ihrem build.gradle (Modul: App-Datei)

dexOptions {
    javaMaxHeapSize "1g"
}

(Fügen Sie diese Zeile in gradle)

 dexOptions {
        javaMaxHeapSize "4g"
    }

Sie können auch durch das Hinzufügen dieser zu Ihrer gradle.properties Dateispeicherzuweisung und Heap-Größe erhöhen:

org.gradle.jvmargs=-Xmx2048M -XX\:MaxHeapSize\=32g

Es muss nicht 2048M und 32g sein, es so groß machen wie Sie wollen.

Sie müssen die Speichergröße in Jdeveloper geht 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 diesen Fehler auftreten, wenn eine signierte APK für die Freigabe zu erzeugen versuchen. Ich konnte eine Debug-APK ohne Probleme bauen und zu testen, aber sobald ich Release APK, der Build-Prozess laufen würde minutenlang und schließlich endet mit dem „Fehler java.lang.OutOfMemoryError bauen wollte: GC Obergrenze überschritten“. Ich erhöhte die Speichergrößen sowohl für die VM und die Android DEX-Compiler, aber das Problem blieb. Endlich, nach vielen Stunden und Tassen Kaffee stellte sich heraus, dass das Problem in meiner app-Ebene ‚build.gradle‘ Datei - ich hatte das ‚minifyEnabled‘ Parameter für die Release-Build Typ auf ‚falsch‘, folglich Proguard stopft läuft auf Code, der durch den Code schrumpf‘-Prozess (siehe https nicht gewesen ist: //developer.android.com/studio/build/shrink-code.html ). Ich habe die 'minifyEnabled' Parameter auf 'true' und den Release-Build wie ein Traum ausgeführt:)

Kurz gesagt, hatte ich meine app-Ebene ‚build.gradle‘ Datei aus zu ändern:     //...

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
    }
}

//...

    //...

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
    }
}

//...

Heap-Größe in IntelliJ IDEA folgen Sie den folgenden Anweisungen zu erhöhen. Er arbeitete für mich.

Für Windows-Benutzer,

Gehen Sie auf die Stelle, an der IDE installiert ist, und die Suche nach folgenden.

idea64.exe.vmoptions

Bearbeiten Sie die Datei und fügen Sie die folgende.

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

Das ist es !!

Neustarten mein MacBook fixiert dieses Problem für mich.

In Netbeans, kann es hilfreich sein, einen max Heap-Größe zu entwerfen. Zur Ausführen => Set Projektkonfiguration => Anpassen . In der Ausführen seiner tauchte Fenster, gehen Sie auf VM Option , fill in -Xms2048m -Xmx2048m. Es könnte Heap-Größe Problem lösen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top