Menu
Coddy logo textTech

Garbage collection en Go

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy. Leçon 23 sur 107.

Contrairement à des langages comme C ou C++, Go gère automatiquement la mémoire grâce au garbage collection (GC). Vous n’avez pas besoin de libérer manuellement la mémoire lorsque vous avez fini de l’utiliser. L’environnement d’exécution de Go suit la mémoire qui est encore utilisée et récupère le reste.

Lorsque vous allouez de la mémoire à l’aide de new(), de make() ou en créant des variables, le ramasse-miettes de Go surveille ces allocations. Dès qu’une valeur n’est plus accessible depuis aucune partie de votre programme, le GC libère automatiquement cette mémoire.

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p s'échappe vers le tas, le GC le gérera
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // Lorsque person n'est plus utilisé, le GC récupère la mémoire
}

Dans cet exemple, la structure Person est allouée sur le tas parce qu’elle est renvoyée par la fonction. Le compilateur de Go effectue une analyse d’échappement pour déterminer si une variable peut rester sur la pile ou doit être déplacée vers le tas. Le ramasse-miettes gère uniquement la mémoire du tas.

Cette gestion automatique de la mémoire signifie que vous pouvez vous concentrer sur la création de votre application sans vous soucier des fuites de mémoire dues à des désallocations oubliées. Cependant, comprendre que le GC existe vous aide à écrire un code plus efficace en minimisant les allocations inutiles lorsque les performances sont importantes.

challenge icon

Défi

Facile

Construisons un gestionnaire de sessions qui montre comment le garbage collector de Go gère la mémoire des objets qui s’échappent vers le tas. Vous créerez des sessions allouées dynamiquement et renvoyées par des fonctions, ce qui permettra au GC de gérer leur cycle de vie.

Vous organiserez votre code sur deux fichiers :

  • session.go : définissez une structure Session avec les champs ID (chaîne), Username (chaîne) et Data (une tranche de chaînes). Créez une fonction NewSession qui prend un ID et un nom d’utilisateur, alloue une nouvelle Session sur le tas (en renvoyant un pointeur) et initialise la tranche Data comme vide. Ajoutez également une méthode AddData avec un récepteur pointeur qui ajoute une chaîne à la tranche Data de la session, ainsi qu’une méthode Summary qui renvoie une chaîne formatée présentant les détails de la session.
  • main.go : lisez les informations de session depuis l’entrée, créez une session à l’aide de votre fonction constructeur, ajoutez-y quelques entrées de données et affichez le résumé de la session. Comme la session est créée à l’intérieur d’une fonction et renvoyée sous forme de pointeur, elle s’échappe vers le tas, où le garbage collector la gérera.

Les entrées suivantes seront fournies :

  • Ligne 1 : ID de session
  • Ligne 2 : Nom d’utilisateur
  • Ligne 3 : Première entrée de données à ajouter
  • Ligne 4 : Deuxième entrée de données à ajouter

Votre méthode Summary doit renvoyer une chaîne dans ce format :

Session [ID] for user [Username]
Data entries: [count]
- [entry1]
- [entry2]

Par exemple, avec sess-001, alice, login et view_dashboard, votre sortie doit être :

Session sess-001 for user alice
Data entries: 2
- login
- view_dashboard

L’idée essentielle ici est que votre fonction NewSession crée une Session et renvoie un pointeur vers celle-ci. Cela entraîne l’« échappement » de la Session vers le tas au lieu de son maintien sur la pile, ce qui la rend éligible au garbage collector dès qu’il ne reste plus aucune référence vers elle. Votre code n’a pas besoin de libérer manuellement cette mémoire : Go s’en charge automatiquement.

Essayez vous-même

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Lire l'ID de session
	sessionID, _ := reader.ReadString('\n')
	sessionID = sessionID[:len(sessionID)-1]

	// Lire le nom d'utilisateur
	username, _ := reader.ReadString('\n')
	username = username[:len(username)-1]

	// Lire la première entrée de données
	data1, _ := reader.ReadString('\n')
	data1 = data1[:len(data1)-1]

	// Lire la deuxième entrée de données
	data2, _ := reader.ReadString('\n')
	data2 = data2[:len(data2)-1]

	// TODO: Créer une nouvelle session en utilisant la fonction NewSession
	// La session s'échappera vers le tas puisque nous retournons un pointeur

	// TODO: Ajouter les entrées de données à la session en utilisant la méthode AddData

	// TODO: Afficher le résumé de la session en utilisant la méthode Summary
	fmt.Println("")
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Go en ligne