GC overhead limit exceeded
Une OutOfMemoryError levée quand la JVM passe presque tout son temps en GC et ne récupère presque rien.
Une OutOfMemoryError levée quand la JVM passe presque tout son temps en GC et ne récupère presque rien.
Parallel GC lève java.lang.OutOfMemoryError: GC overhead limit exceeded quand plus de 98 pour cent du temps est passé en GC et moins de 2 pour cent du tas est récupéré, sur plusieurs collectes complètes consécutives (-XX:+UseGCOverheadLimit, activé par défaut). C'est un symptôme, pas une cause : l'ensemble de données vivantes dépasse le tas, ou une fuite continue de le remplir.
Cherchez dans le log des lignes Pause Full enchaînées qui ne récupèrent presque rien, puis analysez un heap dump (jcmd GC.heap_dump) pour trouver ce qui retient la mémoire. Augmenter -Xmx retarde l'échec mais ne corrige pas une fuite.
Documentation officielle : Troubleshoot Memory Leaks (Oracle)
Débit
La part du temps que l'application passe à travailler utilement plutôt qu'en pauses GC.
Un débit de 99 pour cent signifie une seconde de pauses pour 100 secondes. Le réglage orienté débit (Parallel, grands tas) accepte des pauses plus longues et plus rares. Le réglage orienté latence (ZGC, Shenandoah, G1 avec un objectif de pause bas) accepte un travail plus fréquent et plus court, et dépense plus de CPU dans le collecteur.
GC Doctor calcule le débit à partir des pauses de la plage sélectionnée. Il ignore le travail concurrent, qui consomme du CPU sans arrêter l'application : lisez-le avec la vue CPU.
Full GC
Collecte stop-the-world de tout le tas : marquage puis compactage. La collecte la plus lente ; dans une application saine elle est rare ou absente.
Déclencheurs typiques : plus de place pour promouvoir ou allouer après une collecte jeune (Allocation Failure), un appel explicite à System.gc(), le seuil du metaspace, une demande d'inspection ou de dump du tas, un collecteur concurrent qui a pris du retard. Le coût croît avec les données vivantes, puisqu'il faut toutes les marquer et les déplacer : des secondes sur un tas de plusieurs gigaoctets.
Serial et Parallel collectent leur génération ancienne par une collecte complète par conception. G1 utilise une collecte complète parallèle depuis JDK 10, mais elle reste un dernier recours. Le signe d'un problème, ce sont des collectes complètes fréquentes qui récupèrent peu : l'ensemble de données vivantes est proche de la taille du tas, et l'application fuit ou est sous-dimensionnée. Lisez la cause dans la ligne de log, Pause Full (cause), puis le tas après la collecte. GC Doctor liste chaque full GC avec sa cause et son tas avant et après.
GC overhead limit exceeded