Quel type de récupération de place est utilisé par Go?

111

Go est un langage garbage collection:

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

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

C'est toujours marquer et balayer? Est-ce conservateur ou précis? Est-ce générationnel?

user1003432
la source
2
Pour une longue discussion sur l'histoire du ramasse-miettes Go jusqu'en juillet 2018, voir blog.golang.org/ismmkeynote
Wildcard

Réponses:

117

Plans pour le ramasse-miettes Go 1.4+:

  • collecteur hybride stop-the-world / concurrent
  • partie stop-the-world limitée par un délai de 10 ms
  • 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 très probablement aussi un débit plus faible, que Go 1.3 GC

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

  • balayage simultané (entraîne des temps de pause plus courts)
  • entièrement précis

Go 1.1 garbage collector:

  • mark-and-sweep (implémentation parallèle)
  • non générationnel
  • non compactant
  • principalement précis (sauf cadres de pile)
  • arrêter le monde
  • représentation bitmap
  • zéro coût lorsque le programme n'alloue pas de mémoire (c'est-à-dire que le brassage des pointeurs est aussi rapide qu'en C, bien qu'en pratique cela soit un peu plus lent 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 garbage collector:

  • identique à Go 1.1, mais au lieu d'être principalement précis, le ramasse-miettes est conservateur. Le GC conservateur est capable d'ignorer des objets tels que [] byte.

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

  • à l'exception des très gros tas, on ne sait pas si un GC générationnel serait globalement plus rapide
  • package "unsafe" rend difficile la mise en œuvre d'un GC entièrement précis et le compactage du GC

la source
De plus, le ramasse-miettes actuel a un certain degré de parallélisme afin qu'il puisse fonctionner plus rapidement sur les systèmes multicœurs.
uriel
3
@uriel: Oui, j'ai mentionné cela dans le premier élément de ma réponse - le texte "(mise en œuvre parallèle)".
Cette réponse est-elle toujours d'actualité?
Kim Stebel
c # garbage collector est précis et en c # comme dans go, vous pouvez avoir une référence au membre d'un frappé et c # avoir un mode unsafe mais je ne sais pas comment cela se compare à une implémentation non sécurisée
skyde
3
Que diriez-vous de mettre à jour cette réponse avec 1.5.x juste pour faire un bon journal d'historique.
Ismael
32

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

Le prochain Garbage Collector simultané de Go 1.5 impliquera d'être capable de "rythmer" dit gc.
Voici une proposition présentée dans cet article qui pourrait le faire pour Go 1.5, mais qui 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 parallèle stop-the-world (STW).
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 la présentation GopherCon 2015 « 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é un garbage collection chaque fois que la taille du tas doublait par rapport à la taille du tas en direct à partir de la collection 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 cela 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 la présentation GopherCon 2015 « Go GC: Résoudre le problème de latence dans Go 1.5 »)

Pour atteindre la même limite de croissance du tas, le runtime doit démarrer le ramasse-miettes plus tôt, mais le délai 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 garbage collection, gaspillant les ressources du processeur.
  • Démarrez le collecteur trop tard et l'application dépassera la croissance de tas maximale souhaitée.

Pour atteindre le bon équilibre sans sacrifier la concurrence, il est nécessaire de contrôler soigneusement le ramasse-miettes.

La stimulation GC vise à optimiser selon 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 exigera,
  2. un mécanisme permettant aux mutateurs d'effectuer la quantité estimée de travail d'analyse au moment où l'allocation du tas atteint l'objectif du tas,
  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: le temps CPU et le temps de tas .

  • Le temps CPU est comme l'horloge murale standard, mais passe GOMAXPROCSplus vite.
    Autrement dit, si GOMAXPROCSest 8, alors huit secondes CPU passent chaque seconde de mur et GC obtient deux secondes de temps CPU chaque seconde de mur.
    Le planificateur CPU gère le temps CPU.
  • Le passage du temps de tas est mesuré en octets et avance au fur et à mesure que les mutateurs sont alloués.

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

VonC
la source
20

C'est la mise en œuvre du GC:

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

À partir des documents dans la source:

Le GC fonctionne en même temps que les threads mutateurs, est de type précis (aka précis), permet à plusieurs threads GC de fonctionner en parallèle. Il s'agit d'un marquage et d'un balayage simultanés qui utilise une barrière d'écriture. Il est non générationnel et non compactant. L'allocation est effectuée en utilisant une taille séparée par zones d'allocation P pour minimiser la fragmentation tout en éliminant les verrous dans le cas courant.

berdario
la source
8

Go 1.8 GC pourrait à nouveau évoluer, avec la proposition «Éliminer la réanalyse de la pile STW»

À partir de Go 1.7, la seule source restante de temps d' arrêt du monde (STW) illimité et potentiellement non trivial est le réexamen de la pile.

Nous proposons d'éliminer le besoin de réanalyser la 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 barrière d'écriture d'insertion de style Dijkstra [Dijkstra '78] .

Des expériences préliminaires montrent que cela peut réduire le temps STW dans le cas le plus défavorable à moins de 50 µs , et cette approche peut permettre d'éliminer complètement la terminaison de marque STW.

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

VonC
la source
3

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 plus dans un proche avenir. Peut-être que quelqu'un d'autre pourra clarifier cela plus en détail.

jnml
la source
7
C'est stop-the-world. GC fonctionne potentiellement en parallèle après l'arrêt du monde. Vous vouliez probablement dire GC simultané.