Limiteur de CPU du GC
Garde-fou ajouté en Go 1.19 qui plafonne le temps CPU que le collecteur peut prendre, autour de 50 pour cent, quand la limite mémoire est atteinte.
Garde-fou ajouté en Go 1.19 qui plafonne le temps CPU que le collecteur peut prendre, autour de 50 pour cent, quand la limite mémoire est atteinte.
Avec une limite mémoire proche du tas vivant, le collecteur pourrait tourner en continu et affamer le programme, une spirale de la mort. Le limiteur suit la fraction de CPU utilisée par le GC et les assistances sur une fenêtre glissante et, quand elle dépasse 50 pour cent, laisse le programme allouer au-delà de la limite.
La limite mémoire est donc souple : le programme peut dépasser GOMEMLIMIT temporairement plutôt que de cesser de progresser. Si gctrace montre des cycles enchaînés avec un tas près de la limite, le tas vivant est trop grand pour la limite : relevez-la ou réduisez l'usage mémoire.
Documentation officielle : A Guide to the Go Garbage Collector
GOGC
Le réglage principal du GC de Go : le pourcentage du tas vivant qui peut être alloué avant le démarrage du cycle suivant. La valeur par défaut est 100.
Avec GOGC=100, l'objectif de tas est le double du tas vivant (plus piles et globales, depuis Go 1.18) : un programme avec 100 Mio de tas vivant démarre un cycle vers 200 Mio. Doubler GOGC double la mémoire supplémentaire et divise à peu près par deux le coût CPU du GC, et inversement. On le règle par la variable d'environnement GOGC ou debug.SetGCPercent. GOGC=off désactive le collecteur, ce qui n'est raisonnable qu'avec une limite mémoire.
Dans gctrace, comparez les tailles de tas (au début, à la fin, vivant) avec l'objectif. Un programme au tas vivant petit et stable avec beaucoup de mémoire disponible peut augmenter GOGC pour dépenser moins de CPU en GC. Un programme en conteneur proche de sa limite mémoire doit plutôt utiliser GOMEMLIMIT.
Documentation officielle : A Guide to the Go Garbage Collector
GOMEMLIMIT
Limite souple de la mémoire totale utilisée par le runtime Go, disponible depuis Go 1.19. Le collecteur travaille davantage à mesure qu'on s'en approche.
La limite couvre tout le runtime : tas, piles et structures du runtime, pas la mémoire rendue au système. Quand le total s'en approche, le collecteur tourne plus souvent que GOGC seul ne l'exigerait, échangeant du CPU contre de la mémoire. La limite est souple : si les données vivantes la dépassent vraiment, le programme continue de tourner, et le limiteur de CPU du GC empêche le collecteur de monopoliser le CPU.
Un réglage typique en conteneur est une limite de 5 à 10 pour cent sous la mémoire du conteneur, avec GOGC inchangé ou désactivé. On la règle par la variable GOMEMLIMIT (par exemple 900MiB) ou debug.SetMemoryLimit. Quand la limite contraint, les cycles deviennent fréquents et la part de CPU passée en GC augmente.
Documentation officielle : A Guide to the Go Garbage Collector
Limiteur de CPU du GC