OutOfMemoryError: Limite de temps système GC dépassée

1. Vue d’ensemble

En termes simples, la machine virtuelle Java s’occupe de libérer de la mémoire lorsque des objets ne sont plus utilisés; ce processus s’appelle Garbage Collection (lien:/jvm-garbage-collectors[GC]).

L’erreur GC Overhead Limit Exceeded de la famille java.lang.OutOfMemoryError est une indication de l’épuisement des ressources (mémoire).

Dans cet article, nous allons examiner les causes de l’erreur java.lang.OutOfMemoryError: GC Overhead Limit Exceeded et la façon dont elle peut être résolue.

2. Erreur de dépassement de limite du temps système du GC

OutOfMemoryError est une sous-classe de java.lang.VirtualMachineError ; la machine virtuelle le jette quand elle rencontre un problème lié à l’utilisation des ressources. Plus précisément, l’erreur se produit lorsque la machine virtuelle Java a passé trop de temps à effectuer le nettoyage de la mémoire et n’a pu récupérer que très peu d’espace mémoire.

Selon les documents Java, par défaut, la machine virtuelle Java est configurée pour émettre cette erreur si le processus Java consacre plus de 98% de son temps à la GC et lorsque seulement moins de 2% du segment de mémoire est récupéré à chaque exécution. En d’autres termes, cela signifie que notre application a épuisé presque toute la mémoire disponible et que le récupérateur de place a passé trop de temps à essayer de la nettoyer et a échoué à plusieurs reprises.

Dans cette situation, les utilisateurs rencontrent une lenteur extrême de l’application.

Certaines opérations, qui se terminent généralement en millisecondes, prennent plus de temps. En effet, le processeur utilise toute sa capacité pour le nettoyage de la mémoire et ne peut donc effectuer aucune autre tâche.

3. Erreur en action

Regardons un morceau de code qui jette __java.lang.OutOfMemoryError:

Limite de frais généraux du GC dépassée.__

Nous pouvons y parvenir, par exemple, en ajoutant des paires clé-valeur dans une boucle non terminée:

public class OutOfMemoryGCLimitExceed {
    public static void addRandomDataToMap() {
        Map<Integer, String> dataMap = new HashMap<>();
        Random r = new Random();
        while (true) {
            dataMap.put(r.nextInt(), String.valueOf(r.nextInt()));
        }
    }
}

Lorsque cette méthode est appelée, avec les arguments JVM sous la forme __- Xmx100m -XX: UseParallelGC (la taille du segment de mémoire Java est définie sur 100 Mo et que l’algorithme GC est défini sur ParallelGC), une erreur java.lang.OutOfMemoryError: GC Overhead Limit Limceed est dépassée. Pour obtenir une meilleure compréhension des différents algorithmes de récupération de place, nous pouvons consulter le tutoriel d’Oracle Java Récupération de place .

Vous obtiendrez très rapidement une erreur java.lang.OutOfMemoryError: GC Overhead Limit Exceeded en exécutant la commande suivante à la racine du project :

mvn exec:exec

Il convient également de noter que, dans certaines situations, nous pouvons rencontrer une erreur d’espace de tas avant de rencontrer l’erreur GC Overhead Limit Exceeded .

** 4. Résolution de l’erreur de dépassement de limite du temps système du GC

La solution idéale consiste à rechercher le problème sous-jacent à l’application en examinant le code pour détecter les fuites de mémoire.

Les questions suivantes doivent être abordées:

  • Quels sont les objets de l’application qui occupent de larges portions de

le tas?

  • Dans quelles parties du code source ces objets sont-ils alloués?

Nous pouvons également utiliser des outils graphiques automatisés tels que JConsole , qui permet de détecter les problèmes de performances dans le code, notamment java.lang. .OutOfMemoryErrors.

Le dernier recours consisterait à augmenter la taille du segment en modifiant la configuration de lancement de la machine virtuelle Java. Par exemple, cela donne 1 Go d’espace de tas pour l’application Java:

java -Xmx1024m com.xyz.TheClassName

Toutefois, cela ne résoudra pas le problème s’il existe des fuites de mémoire dans le code de l’application. Au lieu de cela, nous allons simplement reporter l’erreur.

Par conséquent, il est préférable de réévaluer de manière approfondie l’utilisation de la mémoire de l’application.

5. Conclusion

Dans ce tutoriel, nous avons examiné java.lang.OutOfMemoryError: GC Overhead Limit Exceeded et les raisons qui la sous-tendaient.

Comme toujours, le code source lié à cet article est disponible à l’adresse over sur GitHub .