GC explicite (System.gc())
Collecte demandée par du code ou un outil plutôt que par le collecteur lui-même, avec la cause System.gc() ou Diagnostic Command.
Collecte demandée par du code ou un outil plutôt que par le collecteur lui-même, avec la cause System.gc() ou Diagnostic Command.
System.gc(), Runtime.gc() et certaines bibliothèques (nettoyage des tampons directs NIO, GC distribué de RMI, qui tourne toutes les heures par défaut) déclenchent une collecte complète, affichée Pause Full (System.gc()). Les outils d'inspection du tas comme jmap -histo:live et jcmd GC.run en déclenchent aussi une. Les collectes explicites sont stop-the-world et peuvent durer des secondes sur un grand tas.
Elles sont rarement utiles. -XX:+DisableExplicitGC les ignore ; avec G1 ou CMS, -XX:+ExplicitGCInvokesConcurrent les transforme en cycles concurrents. Des pauses qui reviennent à intervalle fixe, une heure d'écart, viennent généralement de RMI.
Documentation officielle : The java command (Oracle)
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.
Pause / Stop-the-world
Période pendant laquelle tous les threads de l'application sont arrêtés pour que le collecteur travaille sur un tas qui ne bouge pas sous ses pieds.
Les pauses sont ce que les utilisateurs ressentent comme de la latence : une requête qui arrive pendant une pause attend toute la pause. Une ligne de log comme Pause Young (Normal) (G1 Evacuation Pause) 24M à 4M (256M) 3.2ms donne la cause, le tas avant et après la collecte, la taille de tas allouée et la durée.
Tout le travail de collecte n'est pas une pause. Les collecteurs modernes (G1, ZGC, Shenandoah) font l'essentiel du marquage en concurrence et gardent les phases stop-the-world courtes, mais certaines étapes en exigent toujours une : démarrer et terminer un cycle de marquage, évacuer les objets vivants dans G1, ou une collecte complète de secours. La durée d'une pause croît avec la quantité de données vivantes à copier ou parcourir, pas avec la quantité de déchets ; ZGC et Shenandoah font exception, leurs pauses ne dépendent presque pas de la taille du tas.
GC Doctor trace chaque pause dans le temps et indique la plus longue, le 99e centile et la part du temps passée en pause.
Documentation officielle : JEP 271: Unified GC Logging
GC explicite (System.gc())