Outils pour utilisateurs

Outils du site


cours:informatique:dev:golang:demarrer_avec_go:225_ramasse_miettes

Notes et transcriptions du cours “Démarrer avec Go” proposée par University of California, Irvine disponible sur la plateforme coursera.

Le garbage collector (ramasse-miettes)

Nous avons donc parlé de désallocation, et de la difficulté de déterminer quand il est approprié de désallouer une variable. La raison en est que vous ne pouvez désallouer une variable que lorsque vous savez qu'elle n'est plus utilisée. Vous ne voulez pas désallouer une variable et avoir ensuite besoin de cette variable précédemment désallouée, car elle serait alors dans un état inconnu.

Il est donc parfois difficile de déterminer quand une variable est utilisé ou pas. Voici un exemple Go.

func foo() *int {
   x := 1
   return &x
}
 
func main () {
   var y *int
   y = foo()
   fmt.Printf("%d", *y)
}

C'est légal en Go, mais comme c'est pénible, ce n'est pas accepté dans certains autres langages. Si vous regardez la première fonction foo(), à l'intérieur, nous déclarons une variable locale x, et ce qui est renvoyé, c'est l'adresse de x, un pointeur vers x.

Dans la fonction main() on appelle foo() et on obtient la valeur de retour de foo(), elle est alors assignée à une variable y dans la fonction principale. La confusion ici, c'est que ce programme fonctionne normalement, si vous déclarez une variable locale x à la fin de la fonction, cette variable x doit être désallouée. C'est vrai : vous en avez terminé avec x parce que la fonction est terminée.

Mais dans ce cas, c'est différent car foo() renvoie un pointeur vers x à main() qui peut toujours utiliser ce pointeur. Vous ne pouvez pas simplement dire « foo est terminé, je peux me débarrasser de sa variable locale x parce que main va peut-être utiliser cette variable locale parce que maintenant main a un pointeur vers elle ».

C'est légal et possible en Go. Ce n'est donc qu'un exemple qui illustre la façon dont les pointeurs rendent particulièrement difficile de savoir quand la désallocation est légale et quand elle ne l'est pas.

La désallocation est donc une chose compliquée. Alors, que font les gens ? L'un des moyens d'y remédier est l'usage du garbage collector (ramasse miettes). Ainsi, le ramasse miettes est essentiellement un outil qui traite automatiquement la désallocation.

C'est une fonctionnalité des langages interprétés et cela est fait par l'interpréteur, donc en Java, c'est la machine virtuelle Java, en Python, c'est un l'interpréteur Python, etc. Le garbage collector garde une trace de ces pointeurs et détermine quand une variable est utilisée et quand elle ne l'est plus.

Une fois qu'il a déterminé qu'une variable n'est définitivement pas utilisée, qu' il n'y a plus de pointeurs, plus de références à cette variable, le ramasse-miettes la désalloue et seulement quand toutes les références ont disparu.

Le ramasse-miettes est une bonne chose, le programmeur n'a pas à se soucier du moment exact de la désallocation, du moment où il faut le faire, du moment où il ne faut pas le faire.

La désallocation de la mémoire est un gros casse-tête, dans d'autres langages comme C. Mais cela nécessite un interpréteur, donc généralement les langages compilés comme C , C++ ne peuvent pas le faire, mais Go est différent et meilleur sur ce point.

Le ramasse-miettes en Go

Go est donc un langage compilé dans lequel le ramasse-miettes est intégrée. C'est donc une fonctionnalité unique de Go qui est vraiment sympa. Par conséquent, le compilateur Go peut déterminer dans une certaine mesure quand suivre ces points et déterminer quand vous les utilisez.

Nous ne détaillerons pas le fonctionnement du ramasse-miettes en Go parce que c'est compliqué. De manière de faire est de suivre les pointeurs vers un objet en particulier. Une fois que tous les pointeurs ont disparu, vous savez que l'objet peut être désalloué.

Ainsi, le ramasse-miettes en Go permet deux choses :

  • Il allouera les éléments sur le tas ou sur la pile lui-même. Donc, en tant que programmeur, vous n'avez pas à le déterminer. Le compilateur Go au moment de la compilation, déterminera que cela doit être mis en tas, que cela doit aller dans la pile ;
  • Il désallouera de manière appropriée.

C'est vraiment utile. Maintenant, il y a un inconvénient car le ramasse-miettes prend un certain temps, c'est vrai. Il y a donc un impact sur les performances, mais c'est une implémentation assez efficace et le ramasse-miettes est tellement utile qu'elle vaut probablement la peine de la mettre dans Go, en arrière plan. C'est donc un compromis que fait Go. Cela ralentit un peu les choses, mais c' est un avantage considérable car cela facilite beaucoup la programmation sans aller jusqu'à l'usage complet d'un interpréteur.

◁ Précédent | ⌂ Retour au sommaire | Suivant

cours/informatique/dev/golang/demarrer_avec_go/225_ramasse_miettes.txt · Dernière modification : 2024/05/12 12:32 de yoann