web-dev-qa-db-fra.com

Quel type de collecte des déchets Go utilise-t-il?

Go est une langue récupérée:

http://golang.org/doc/go_faq.html#garbage_collection

Ici, il est dit que c'est un ramasse-miettes, mais il ne plonge pas dans les détails, et un remplacement est en cours ... pourtant, ce paragraphe ne semble pas avoir été mis à jour depuis la sortie de Go.

C'est toujours du marquage et du balayage? Est-ce conservateur ou précis? Est-ce générationnel?

102
user1003432

Plans pour le ramasse-miettes Go 1.4+:

  • collecteur hybride stop-the-world/simultané
  • partie stop-the-world limitée par un délai de 10ms
  • Cœurs de processeur dédiés à l'exécution du collecteur simultané
  • algorithme de marquage et de balayage tricolore
  • non générationnel
  • non compactant
  • entièrement précis
  • entraîne un petit coût si le programme déplace des pointeurs
  • latence plus faible, mais aussi probablement plus faible débit, que Go 1.3 GC

Mises à jour du garbage collector de Go 1.3 en plus de Go 1.1:

  • balayage simultané (réduit les temps de pause)
  • entièrement précis

Go 1.1 ramasse-miettes:

  • mark-and-sweep (implémentation parallèle)
  • non générationnel
  • non compactant
  • surtout précis (sauf les cadres de pile)
  • arrêter le monde
  • représentation bitmap
  • coût nul lorsque le programme n'alloue pas de mémoire (c'est-à-dire que le réarrangement des pointeurs est aussi rapide qu'en C, bien qu'en pratique cela fonctionne un peu plus lentement que C car le compilateur Go n'est pas aussi avancé que les compilateurs C tels que GCC)
  • prend en charge les finaliseurs sur les objets
  • il n'y a pas de support pour les références faibles

Go 1.0 collecteur de déchets:

  • identique à Go 1.1, mais au lieu d'être surtout précis, le garbage collector est conservateur. Le GC conservateur est capable d'ignorer des objets tels que [] octet.

Le remplacement du GC par un autre est controversé, par exemple:

  • à l'exception des très grands tas, il n'est pas clair si un GC générationnel serait globalement plus rapide
  • le paquet "peu sûr" rend difficile la mise en œuvre de GC entièrement précis et de GC de compactage
109
user811773

(Pour Go 1.8 - Q1 2017, voir ci-dessous )

Le prochain Go 1.5 concurrent Garbage Collector implique de pouvoir "cadencer" ledit gc.
Voici une proposition présentée dans cet article qui pourrait le faire pour Go 1.5, mais aide également à comprendre le GC dans Go.

Vous pouvez voir l'état avant 1.5 (Stop The World: STW)

Avant Go 1.5, Go utilisait un collecteur stop-the-world (STW) parallèle.
Bien que la collection STW présente de nombreux inconvénients, elle a au moins un comportement de croissance de tas prévisible et contrôlable.

https://40.media.tumblr.com/49e6556b94d75de1050c62539680fcf9/tumblr_inline_nr6qq8D9FE1sdck2n_540.jpg

(Photo de GopherCon 2015 présentation " Go GC: Résoudre le problème de latence dans Go 1.5 ")

Le seul bouton de réglage pour le collecteur STW était "GOGC", la croissance relative du tas entre les collections. Le paramètre par défaut, 100%, a déclenché la récupération de place à chaque fois que la taille de segment de mémoire double par rapport à la taille de segment de mémoire dynamique à partir de la collecte précédente:

https://docs.google.com/drawings/image?id=sLJ_JvGfPfPnojLlEGLCWkw&rev=1&h=113&w=424&ac=1

Synchronisation GC dans le collecteur STW.

Go 1.5 introduit un collecteur simultané.
Cela présente de nombreux avantages par rapport à la collecte STW, mais il m rend la croissance du tas plus difficile à contrôler car l'application peut allouer de la mémoire pendant que le garbage collector est en cours d'exécution.

https://40.media.tumblr.com/783c6e557b427a5c023520578740eb94/tumblr_inline_nr6qqpmaJx1sdck2n_540.jpg

(Photo de GopherCon 2015 présentation " Go GC: Résoudre le problème de latence dans Go 1.5 ")

Pour atteindre la même limite de croissance de tas, le runtime doit démarrer le garbage collection plus tôt, mais combien plus tôt dépend de nombreuses variables, dont beaucoup ne peuvent pas être prédites.

  • Démarrez le collecteur trop tôt et l'application effectuera trop de récupérations de déchets, gaspillant les ressources CPU.
  • Démarrez le collecteur trop tard et l'application dépassera la croissance maximale souhaitée du segment de mémoire.

Atteindre le bon équilibre sans sacrifier la simultanéité nécessite de bien arpenter le ramasse-miettes.

La stimulation GC vise à optimiser deux dimensions: la croissance du tas et le processeur utilisé par le garbage collector.

https://docs.google.com/drawings/image?id=sEZYCf7Mc0E0EGmy4gho3_w&rev=1&h=235&w=457&ac=1

La conception de la stimulation GC comprend quatre éléments:

  1. un estimateur de la quantité de travail de numérisation qu'un cycle GC nécessitera,
  2. un mécanisme permettant aux mutateurs d'effectuer la quantité estimée de travail d'analyse au moment où l'allocation de segment de mémoire atteint l'objectif de segment de mémoire,
  3. un planificateur pour l'analyse en arrière-plan lorsque le mutateur aide à sous-utiliser le budget du processeur, et
  4. un contrôleur proportionnel pour le déclencheur GC.

La conception équilibre deux vues différentes du temps: temps CPU et temps de segment.

  • CPU time est comme l'heure standard de l'horloge murale, mais passe GOMAXPROCS fois plus rapidement.
    Autrement dit, si GOMAXPROCS est égal à 8, huit secondes de processeur passent toutes les secondes du mur et le GC obtient deux secondes de temps de processeur par seconde de mur.
    Le planificateur CPU gère le temps CPU.
  • Le passage de heap time est mesuré en octets et avance à mesure que les mutateurs l'allouent.

La relation entre le temps de segment et le temps de mur dépend du taux d'allocation et peut changer constamment.
Mutator aide à gérer le passage du temps de segment de mémoire, garantissant que le travail d'analyse estimé est terminé au moment où le segment de mémoire atteint la taille cible.
Enfin, le contrôleur de déclenchement crée une boucle de rétroaction qui relie ces deux vues du temps, en optimisant à la fois les objectifs de temps de segment et de temps CPU.

31
VonC

Voici la mise en œuvre du GC:

https://github.com/golang/go/blob/master/src/runtime/mgc.go

À partir des documents de la source:

Le GC s'exécute simultanément avec les threads de mutation, est précis (aka précis), permet à plusieurs threads GC de fonctionner en parallèle. Il s'agit d'une marque et d'un balayage simultanés qui utilisent une barrière d'écriture. Elle est non générationnelle et non compactante. L'allocation se fait à l'aide de tailles séparées par zones d'allocation P pour minimiser la fragmentation tout en éliminant les verrous dans le cas commun.

18
berdario

Go 1.8 GC pourrait évoluer à nouveau, avec la proposition "Éliminer la nouvelle analyse de la pile STW"

Depuis Go 1.7, la seule source restante de temps illimité et potentiellement non trivial stop-the-world (STW) est la nouvelle analyse de la pile.

Nous proposons d'éliminer la nécessité d'une nouvelle analyse de pile en passant à une barrière d'écriture hybride qui combine une barrière d'écriture de suppression de style Yuasa [Yuasa '90] et une écriture d'insertion de style Dijkstra barrière [Dijkstra '78] .

Des expériences préliminaires montrent que cela peut réduire le temps STW dans le pire des cas à moins de 50µs , et cette approche peut rendre pratique l'élimination complète de la marque STW.

Le l'annonce est ici et vous pouvez voir que le commit source pertinent est d70b0fe et antérieur.

8
VonC

Je ne suis pas sûr, mais je pense que le GC (tip) actuel est déjà parallèle ou du moins c'est un WIP. Ainsi, la propriété stop-the-world ne s'applique plus ou ne le sera pas dans un avenir proche. Peut-être que quelqu'un d'autre peut clarifier cela plus en détail.

2
jnml