Menu
Coddy logo textTech

Garbage Collection in Go

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy — Lektion 23 von 107.

Im Gegensatz zu Sprachen wie C oder C++ verwaltet Go die Speicherverwaltung automatisch durch Garbage Collection (GC). Sie müssen den Speicher nicht manuell freigeben, wenn Sie ihn nicht mehr benötigen. Die Go-Laufzeitumgebung verfolgt, welcher Speicher noch in Gebrauch ist, und gibt den Rest wieder frei.

Wenn Sie Speicher mit new(), make() oder durch das Erstellen von Variablen zuweisen, überwacht der Garbage Collector von Go diese Allokationen. Sobald ein Wert von keinem Teil Ihres Programms mehr erreichbar ist, gibt der GC diesen Speicher automatisch frei.

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p entweicht auf den Heap, der GC wird es verwalten
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // Wenn person nicht mehr verwendet wird, gibt der GC den Speicher wieder frei
}

In diesem Beispiel wird die Person-struct auf dem Heap zugewiesen, da sie von der Funktion zurückgegeben wird. Der Go-Compiler führt eine Escape-Analyse durch, um zu bestimmen, ob eine Variable auf dem Stack bleiben kann oder auf den Heap verschoben werden muss. Der Garbage Collector verwaltet nur den Heap-Speicher.

Diese automatische Speicherverwaltung bedeutet, dass Sie sich auf die Erstellung Ihrer Anwendung konzentrieren können, ohne sich über Speicherlecks durch vergessene Deallokationen Gedanken machen zu müssen. Das Verständnis, dass GC existiert, hilft Ihnen jedoch dabei, effizienteren Code zu schreiben, indem unnötige Allokationen minimiert werden, wenn es auf die Performance ankommt.

challenge icon

Aufgabe

Einfach

Lassen Sie uns einen Session-Manager erstellen, der demonstriert, wie der Garbage Collector von Go den Speicher für Objekte verwaltet, die auf den Heap "escapen". Sie werden Sessions erstellen, die dynamisch zugewiesen und von Funktionen zurückgegeben werden, sodass der GC ihren Lebenszyklus verwaltet.

Sie werden Ihren Code auf zwei Dateien aufteilen:

  • session.go: Definieren Sie ein Session-Struct mit den Feldern ID (string), Username (string) und Data (ein Slice von Strings). Erstellen Sie eine NewSession-Funktion, die eine ID und einen Benutzernamen entgegennimmt, eine neue Session auf dem Heap zuweist (indem sie einen Pointer zurückgibt) und das Data-Slice als leer initialisiert. Fügen Sie außerdem eine AddData-Methode mit einem Pointer-Receiver hinzu, die einen String an das Data-Slice der Session anhängt, sowie eine Summary-Methode, die einen formatierten String mit den Session-Details zurückgibt.
  • main.go: Lesen Sie Session-Informationen aus der Eingabe ein, erstellen Sie eine Session mit Ihrer Konstruktor-Funktion, fügen Sie einige Dateneinträge hinzu und zeigen Sie die Session-Zusammenfassung an. Da die Session innerhalb einer Funktion erstellt und als Pointer zurückgegeben wird, "escaped" sie auf den Heap, wo der Garbage Collector sie verwalten wird.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Session ID
  • Zeile 2: Username
  • Zeile 3: Erster Dateneintrag zum Hinzufügen
  • Zeile 4: Zweiter Dateneintrag zum Hinzufügen

Ihre Summary-Methode sollte einen String in diesem Format zurückgeben:

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

Zum Beispiel, gegeben sess-001, alice, login und view_dashboard, sollte Ihre Ausgabe wie folgt aussehen:

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

Die entscheidende Erkenntnis hierbei ist, dass Ihre NewSession-Funktion eine Session erstellt und einen Pointer darauf zurückgibt. Dies führt dazu, dass die Session auf den Heap "escaped", anstatt auf dem Stack zu bleiben, wodurch sie für die Garbage Collection infrage kommt, sobald keine Referenzen mehr auf sie existieren. Ihr Code muss diesen Speicher nicht manuell freigeben – Go erledigt das automatisch.

Spickzettel

Go verwendet Garbage Collection (GC) für die automatische Speicherverwaltung. Sie müssen den Speicher nicht manuell freigeben.

Der Garbage Collector verfolgt Speicherallokationen und gibt Speicher frei, der für Ihr Programm nicht mehr erreichbar ist.

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p entweicht auf den Heap, GC wird ihn verwalten
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // Wenn person nicht mehr verwendet wird, gibt der GC den Speicher frei
}

Der Go-Compiler führt eine Escape-Analyse durch, um festzustellen, ob eine Variable auf dem Stack bleibt oder auf den Heap verschoben wird. Variablen, die auf den Heap entweichen (wie zurückgegebene Pointer), werden vom Garbage Collector verwaltet.

Der GC verwaltet nur den Heap-Speicher, nicht den Stack-Speicher. Stack-Speicher wird automatisch freigegeben, wenn eine Funktion zurückkehrt.

Probier es selbst

package main

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

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

	// Session-ID lesen
	sessionID, _ := reader.ReadString('\n')
	sessionID = sessionID[:len(sessionID)-1]

	// Benutzernamen lesen
	username, _ := reader.ReadString('\n')
	username = username[:len(username)-1]

	// Ersten Dateneintrag lesen
	data1, _ := reader.ReadString('\n')
	data1 = data1[:len(data1)-1]

	// Zweiten Dateneintrag lesen
	data2, _ := reader.ReadString('\n')
	data2 = data2[:len(data2)-1]

	// TODO: Erstelle eine neue Sitzung mit der Funktion NewSession
	// Die Sitzung wird in den Heap verschoben (escape to the heap), da wir einen Pointer zurückgeben

	// TODO: Füge die Dateneinträge mit der Methode AddData zur Sitzung hinzu

	// TODO: Gib die Sitzungszusammenfassung mit der Methode Summary aus
	fmt.Println("")
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung