Fehler java.lang.OutOfMemoryError: GC Obergrenze überschritten
-
21-09-2019 - |
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?
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:
- Erhöhen Sie die Speichergröße, zum Beispiel
-Xmx1g
. - Aktivieren Sie die gleichzeitige niedrigen Pause Kollektor
-XX:+UseConcMarkSweepGC
. - 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 ...
reduzierenUrsache 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
- Erhöhen Sie die Heap-Größe , wenn die aktuelle Heap ist nicht genug.
- 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.
- 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
-
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
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:
- Öffnen Sie die Datei
eclipse.ini
-
Ändern
-Xms40m -Xmx512m
-Xms512m -Xmx1024m
-
Starten Sie Eclipse-
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.