web-dev-qa-db-fra.com

Erreur Java.lang.OutOfMemoryError: limite de surcharge du GC dépassée

Je reçois ce message d'erreur lorsque j'exécute mes tests JUnit:

Java.lang.OutOfMemoryError: GC overhead limit exceeded

Je sais ce qu'est une OutOfMemoryError, mais que signifie limite de temps système GC? Comment puis-je résoudre ça?

741
Mnementh

Ce message signifie que, pour une raison quelconque, le ramasse-miettes prend trop de temps (par défaut, 98% du temps CPU du processus) et récupère très peu de mémoire à chaque exécution (par défaut, 2% du tas).

Cela signifie effectivement que votre programme cesse de progresser et est occupé à exécuter uniquement le nettoyage de la mémoire à tout moment.

Pour empêcher votre application d’absorber le temps CPU sans rien faire, la machine virtuelle Java envoie cette variable Error afin que vous puissiez diagnostiquer le problème.

Les rares cas où j'ai vu cela se produire sont ceux où du code créait des tonnes d'objets temporaires et des tonnes d'objets faiblement référencés dans un environnement déjà très contraint en mémoire.

Découvrez cet article pour plus de détails (spécifiquement cette partie ).

713
Joachim Sauer

Le GC lève cette exception lorsque trop de temps est passé dans la récupération de place pour un retour trop faible, par exemple. 98% du temps processeur est consacré au CPG et moins de 2% du segment est récupéré.

Cette fonctionnalité est conçue pour empêcher les applications de s'exécuter pendant une période prolongée tout en faisant peu ou pas de progrès car le tas est trop petit.

Vous pouvez désactiver cette option avec l'option de ligne de commande -XX:-UseGCOverheadLimit

Plus d'infos ici

EDIT: on dirait que quelqu'un peut taper plus vite que moi :)

198
dave

Si vous êtes sûr qu'il n'y a pas de fuite de mémoire dans votre programme, essayez de:

  1. Augmentez la taille du segment, par exemple -Xmx1g.
  2. Activez le collecteur simultané basse pause -XX:+UseConcMarkSweepGC.
  3. Réutilisez les objets existants lorsque cela est possible pour économiser de la mémoire.

Si nécessaire, le limite peut être désactivé en ajoutant l'option -XX:-UseGCOverheadLimit à la ligne de commande.

82
Vitalii Fedorenko

C'est généralement le code. Voici un exemple simple:

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");
    }
}

Utilisation de Java 1.6.0_24-b07 Sous Windows7 32 bits.

Java -Xloggc: gc.log GarbageCollector

Alors regardez gc.log

  • Déclenché 444 fois en utilisant la méthode BAD
  • Déclenché 666 fois à l'aide de la méthode WORSE
  • Déclenché 354 fois en utilisant la méthode BETTER

Maintenant accordé, ce n’est pas le meilleur test ou la meilleure conception, mais face à une situation dans laquelle vous n’avez pas le choix de mettre en place une telle boucle ou lorsque vous traitez avec du code existant qui se comporte mal, choisir de réutiliser des objets plutôt que d’en créer de nouveaux peut réduire le nombre de fois où le ramasse-miettes se met en travers du chemin ...

41
Mike

Cause de la erreur

Limite de temps système GC dépassée "indique que le ramasse-miettes fonctionne tout le temps et que le programme Java progresse très lentement.

Après une récupération de place, si le processus Java passe plus de 98% de son temps environ dans cette tâche et s'il récupère moins de 2% du segment de mémoire et s'il le fait déjà jusqu’à présent, les 5 dernières collectes de mémoire consécutives (constante de temps de compilation) consécutives, puis un Java.lang.OutOfMemoryError est renvoyé.

  1. Augmentez la taille du segment si le segment actuel n'est pas suffisant.
  2. Si vous obtenez toujours cette erreur après avoir augmenté la mémoire de mémoire, utilisez la mémoire , outils de profilage tels que MAT (outil d'analyse de la mémoire), Visual VM etc. et corrigez les fuites de mémoire.
  3. Mettez à niveau la version du JDK vers la dernière version (1.8.x) ou au moins 1.7.x et utilisez l'algorithme G1GC. . L’objectif de débit pour le CPG G1 est de 90% de temps d’application et de 10% de temps de récupération de place
  4. En plus de définir la mémoire de tas avec -Xms1g -Xmx2g, essayez

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

Jetez un coup d'œil à d'autres questions connexes sur G1GC

récupération de place Java 7 (JDK 7) et documentation sur G1

ramasse-miettes Java G1 en production

article Oracle sur le technetwork pour l’ajustement fin du GC

31
Ravindra babu

Il suffit d’augmenter un peu la taille du tas en définissant cette option dans

Exécuter → Exécuter les configurations → Arguments → VM arguments

-Xms1024M -Xmx2048M

Xms - pour la limite minimale

Xmx - pour la limite maximale

27
chopss

Pour moi, les étapes suivantes ont fonctionné:

  1. Ouvrez le fichier Eclipse.ini
  2. Changement

    -Xms40m
    -Xmx512m
    

    à

    -Xms512m
    -Xmx1024m
    
  3. Redémarrer Eclipse

voir ici

14
Sunil Kumar Sahoo

Ce qui suit a fonctionné pour moi. Ajoutez simplement l'extrait suivant:

Android {
        compileSdkVersion 25
        buildToolsVersion '25.0.1'

defaultConfig {
        applicationId "yourpackage"
        minSdkVersion 10
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
dexOptions {
        javaMaxHeapSize "4g"
    }
}
11
H.S.H

essaye ça

ouvrez le fichier build.gradle

  Android {
        dexOptions {
           javaMaxHeapSize = "4g"
        }
   }
11
alicanozkara

augmenter javaMaxHeapsize dans votre fichier build.gradle (Module: app)

dexOptions {
    javaMaxHeapSize "1g"
}

à (Ajouter cette ligne dans le titre)

 dexOptions {
        javaMaxHeapSize "4g"
    }
5
saigopi

Le redémarrage de mon MacBook a résolu ce problème pour moi.

1
Thomas

Vous pouvez également augmenter l’allocation de mémoire et la taille de tas en ajoutant ceci à votre fichier gradle.properties:

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

Il n'est pas nécessaire que ce soit 2048M et 32g, le rendre aussi grand que vous le souhaitez.

1
John Doe

Vous devez augmenter la taille de la mémoire dans Jdeveloper. Allez à 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**
)

et

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**
0
shashi

Je travaille dans Android Studio et j'ai rencontré cette erreur en essayant de générer un fichier APK signé pour publication. J'ai été capable de construire et de tester un APK de débogage sans problème, mais dès que je voulais construire un APK de version, le processus de construction fonctionnait pendant des minutes et finissait par se terminer par le message "Erreur Java.lang.OutOfMemoryError: GC limite de dépassement dépassée ". J'ai augmenté la taille des segments de mémoire pour le compilateur VM et Android DEX, mais le problème persistait. Enfin, après de nombreuses heures et des tasses de café, il est apparu que le problème se trouvait dans mon fichier "build.gradle" au niveau de l'application. J'avais le paramètre 'minifyEnabled' pour le type de construction de la version défini sur 'false', ce qui a entraîné l'exécution de fichiers Proguard sur le code qui n'a pas encore subi le processus de réduction de code (voir https://developer.Android.com/studio/build/shrink-code.html ). J'ai remplacé le paramètre 'minifyEnabled' par 'true' et la compilation a été exécutée comme un rêve :)

En bref, je devais changer mon fichier 'build.gradle' au niveau de l'application à partir de: // ...

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

//...
0
Alex Ivan Howard

Pour augmenter la taille de la mémoire dans IntelliJ IDEA, suivez les instructions suivantes. Cela a fonctionné pour moi.

Pour les utilisateurs Windows,

Accédez à l'emplacement où IDE est installé et recherchez les éléments suivants.

idea64.exe.vmoptions

Editez le fichier et ajoutez ce qui suit.

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

C'est ça !!

0
Dulith De Costa