Errore java.lang.OutOfMemoryError: limite di GC in testa superato
-
21-09-2019 - |
Domanda
ricevo questo messaggio di errore, come ho eseguire il mio test JUnit:
java.lang.OutOfMemoryError: GC overhead limit exceeded
So cosa un OutOfMemoryError
è, ma che cosa significa limite di GC in testa? Come posso risolvere questo?
Soluzione
Questo messaggio significa che per qualche motivo il garbage collector sta prendendo una quantità eccessiva di tempo (per default 98% del tempo di CPU del processo) e recupera molto poca memoria in ciascuna serie (di default 2% del mucchio) .
Questo significa che il vostro programma non facendo alcun progresso ed è occupato in esecuzione solo la raccolta dei rifiuti in tutti i tempi.
Per evitare che l'applicazione da godersi il tempo di CPU senza ottenere nulla di fatto, la JVM genera questa Error
in modo da avere la possibilità di diagnosticare il problema.
I rari casi in cui ho visto che questo accada è dove alcuni codice è stato la creazione di tonnellate di oggetti temporanei e tonnellate di oggetti debolmente riferimento in un ambiente già molto memoria limitata.
questo articolo per informazioni ( href="http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#par_gc.oom" questa parte ) .
Altri suggerimenti
Il GC genera questa eccezione quando troppo tempo è trascorso in garbage collection per troppo poco di ritorno, ad esempio. 98% del tempo di CPU viene speso per GC e meno del 2% del cumulo viene recuperato.
Questa funzione è stata progettata per evitare che le applicazioni in esecuzione per un periodo prolungato di tempo mentre facendo pochi o nessun progresso, perché il cumulo è troppo piccolo.
È possibile disattivare questo con l'opzione di riga di comando
-XX:-UseGCOverheadLimit
Più informazioni qui
EDIT: sembra che qualcuno può digitare più velocemente di me:)
Se sei sicuro che non vi siano perdite di nel programma, cercare di:
- Aumentare la dimensione heap, per esempio
-Xmx1g
. - Attivare il concomitante partire
-XX:+UseConcMarkSweepGC
pausa collettore. - riutilizzare gli oggetti esistenti quando è possibile risparmiare un po 'di memoria.
Se necessario, il controllo limite può essere disabilitata aggiungendo l'opzione -XX:-UseGCOverheadLimit
alla riga di comando.
Di solito è il codice. Ecco un semplice esempio:
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");
}
}
Utilizzo di Java 1.6.0_24-b07 Su un Windows7 32 bit.
java -Xloggc: gc.log GarbageCollector
Poi guardate gc.log
- innescate 444 volte utilizzando il metodo BAD
- innescate 666 volte utilizzando il metodo PEGGIO
- innescate 354 volte utilizzando metodo migliore
Ora concesso, questo non è il miglior test o il miglior design, ma di fronte a una situazione in cui non hai scelta, ma l'attuazione di tale ciclo o quando si tratta di codice che si comporta male esistente, scegliendo di riutilizzare gli oggetti invece di creare nuovi quelli in grado di ridurre il numero di volte che il garbage collector intralcia ...
Causa per l'errore rel="noreferrer">
Limite GC in testa superato" indica che il garbage collector è in esecuzione tutto il tempo e programma Java sta compiendo progressi molto lenti.
Dopo una garbage collection, se il processo di Java sta spendendo più di circa il 98% del suo tempo a fare la raccolta dei rifiuti e se si sta riprendendo meno del 2% del mucchio e ha fatto finora gli ultimi 5 (tempo di compilazione costante) garbage collection consecutivi, poi un java.lang.OutOfMemoryError è gettato
- Aumentare la dimensione heap se mucchio attuale non è sufficiente.
- Se viene ancora questo errore dopo l'aumento di memoria heap, usare la memoria profilatura Strumenti come MAT (strumento analizzatore di memoria), visiva VM ecc e risolvere le perdite di memoria.
- Aggiornamento versione JDK alla versione più recente (1.8.x) o almeno 1.7.x e utilizzare l'algoritmo G1GC. . L'obiettivo di throughput per il G1 GC è tempo di applicazione del 90 per cento e il 10 per cento di tempo la raccolta dei rifiuti
-
A parte l'impostazione della memoria heap con -
Xms1g -Xmx2g
, provare-XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m -XX:ParallelGCThreads=n -XX:ConcGCThreads=n
Date un'occhiata ad alcune domande più correlati riguardanti G1GC
Java 7 (JDK 7) raccolta dei rifiuti e documentazione su G1
Basta aumentare la dimensione heap un po impostando questa opzione in
Run Run → Configurazioni → Argomenti → argomenti VM
-Xms1024M -Xmx2048M
Xms - per il limite minimo
Xmx - per il limite massimo di
Per quanto mi riguarda, le seguenti operazioni hanno lavorato:
- Apri il file
eclipse.ini
-
Cambia
-Xms40m -Xmx512m
a
-Xms512m -Xmx1024m
-
riavviare Eclipse
provare questo
aprire il file build.gradle
android {
dexOptions {
javaMaxHeapSize = "4g"
}
}
Di seguito ha lavorato per me. Basta aggiungere il seguente frammento:
android {
compileSdkVersion 25
buildToolsVersion '25.0.1'
defaultConfig {
applicationId "yourpackage"
minSdkVersion 10
targetSdkVersion 25
versionCode 1
versionName "1.0"
multiDexEnabled true
}
dexOptions {
javaMaxHeapSize "4g"
}
}
aumento javaMaxHeapsize nel build.gradle (Modulo: app) file
dexOptions {
javaMaxHeapSize "1g"
}
a (Aggiungere questa linea in Gradle)
dexOptions {
javaMaxHeapSize "4g"
}
È inoltre possibile aumentare l'allocazione di memoria e dimensione heap aggiungendo questo al vostro file gradle.properties
:
org.gradle.jvmargs=-Xmx2048M -XX\:MaxHeapSize\=32g
Non deve essere 2048M e 32g, renderlo il più grande come si desidera.
È necessario aumentare la dimensione della memoria in JDeveloper andare a setDomainEnv.cmd .
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**
)
e
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**
sto lavorando in Android Studio e incontrato questo errore quando si cerca di generare un APK firmato per il rilascio. Sono stato in grado di costruire e testare un APK di debug senza alcun problema, ma non appena ho voluto costruire un rilascio APK, il processo di compilazione correrebbe per minuti e poi finalmente terminare con il "Errore java.lang.OutOfMemoryError: GC limite sovraccarico superato". Ho aumentato le dimensioni di heap sia per la VM e il compilatore DEX Android, ma il problema persisteva. Infine, dopo molte ore e tazze di caffè si è scoperto che il problema era nella mia app-livello 'build.gradle' di file - ho avuto il parametro 'minifyEnabled' per il tipo di rilascio di generazione impostato su 'false', di conseguenza, in esecuzione stoffe Proguard il codice che non è stato attraverso il processo di code-restringimento'(vedi https: //developer.android.com/studio/build/shrink-code.html ). Ho cambiato il parametro 'minifyEnabled' a 'vero' e la build di rilascio eseguito come un sogno:)
In breve, ho dovuto cambiare la mia app-livello 'build.gradle' file da: //...
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
}
}
//...
a
//...
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
}
}
//...
Per aumentare dimensione heap in IntelliJ IDEA seguire le seguenti istruzioni. Ha funzionato per me.
Per gli utenti di Windows,
Vai alla posizione in cui è installato IDE e la ricerca di seguito.
idea64.exe.vmoptions
Modificare il file e aggiungere la seguente.
-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m
Questo è tutto !!
Il riavvio il mio MacBook ha risolto questo problema per me.
In Netbeans, può essere utile per la progettazione di una dimensione massima di heap. Vai a Esegui => set di configurazione del progetto => Personalizza . Nel Esegui della sua finestra spuntato, andare a VM Option , compilare -Xms2048m -Xmx2048m
. Si potrebbe risolvere il problema dimensione heap.