Menu
Coddy logo textTech

Garbage Collection en Go

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy — lección 23 de 107.

A diferencia de lenguajes como C o C++, Go maneja la gestión de memoria automáticamente a través de la recolección de basura (GC). No es necesario liberar la memoria manualmente cuando hayas terminado de usarla. El runtime de Go rastrea qué memoria todavía está en uso y reclama el resto.

Cuando asignas memoria usando new(), make() o creando variables, el recolector de basura de Go monitorea estas asignaciones. Una vez que un valor ya no es alcanzable por ninguna parte de tu programa, el GC libera automáticamente esa memoria.

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p escapa al heap, el GC lo gestionará
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // Cuando person ya no se utiliza, el GC reclama la memoria
}

En este ejemplo, la estructura Person se asigna en el heap porque se devuelve desde la función. El compilador de Go realiza un análisis de escape para determinar si una variable puede permanecer en el stack o debe moverse al heap. El recolector de basura solo gestiona la memoria del heap.

Esta gestión automática de memoria significa que puedes centrarte en construir tu aplicación sin preocuparte por las fugas de memoria debidas a desasignaciones olvidadas. Sin embargo, comprender que el GC existe te ayuda a escribir un código más eficiente al minimizar las asignaciones innecesarias cuando el rendimiento es importante.

challenge icon

Desafío

Fácil

Vamos a construir un gestor de sesiones que demuestre cómo el recolector de basura (garbage collector) de Go maneja la memoria para los objetos que escapan al heap. Crearás sesiones que se asignan dinámicamente y se devuelven desde funciones, permitiendo que el GC gestione su ciclo de vida.

Organizarás tu código en dos archivos:

  • session.go: Define una estructura Session con los campos ID (string), Username (string) y Data (un slice de strings). Crea una función NewSession que reciba un ID y un nombre de usuario, asigne una nueva Session en el heap (devolviendo un puntero) e inicialice el slice Data como vacío. También añade un método AddData con un receptor de puntero que añada un string al slice Data de la sesión, y un método Summary que devuelva un string formateado mostrando los detalles de la sesión.
  • main.go: Lee la información de la sesión desde la entrada, crea una sesión usando tu función constructora, añade algunas entradas de datos a ella y muestra el resumen de la sesión. Dado que la sesión se crea dentro de una función y se devuelve como un puntero, escapa al heap donde el recolector de basura la gestionará.

Se proporcionarán las siguientes entradas:

  • Línea 1: Session ID
  • Línea 2: Username
  • Línea 3: Primera entrada de datos a añadir
  • Línea 4: Segunda entrada de datos a añadir

Tu método Summary debe devolver un string con este formato:

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

Por ejemplo, dados sess-001, alice, login y view_dashboard, tu salida debería ser:

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

La idea clave aquí es que tu función NewSession crea una Session y devuelve un puntero a ella. Esto hace que la Session "escape" al heap en lugar de quedarse en el stack, lo que la hace elegible para la recolección de basura una vez que no queden referencias a ella. Tu código no necesita liberar manualmente esta memoria; Go lo maneja automáticamente.

Hoja de referencia

Go utiliza la recolección de basura (GC) para la gestión automática de la memoria. No es necesario liberar la memoria manualmente.

El recolector de basura rastrea las asignaciones de memoria y reclama la memoria que ya no es accesible por su programa.

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p escapes to heap, GC will manage it
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // When person is no longer used, GC reclaims memory
}

El compilador de Go realiza un análisis de escape para determinar si una variable permanece en la pila (stack) o se mueve al montón (heap). Las variables que escapan al montón (como los punteros devueltos) son gestionadas por el recolector de basura.

El GC solo gestiona la memoria del montón, no la memoria de la pila. La memoria de la pila se libera automáticamente cuando una función retorna.

Pruébalo tú mismo

package main

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

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

	// Leer el ID de sesión
	sessionID, _ := reader.ReadString('\n')
	sessionID = sessionID[:len(sessionID)-1]

	// Leer el nombre de usuario
	username, _ := reader.ReadString('\n')
	username = username[:len(username)-1]

	// Leer la primera entrada de datos
	data1, _ := reader.ReadString('\n')
	data1 = data1[:len(data1)-1]

	// Leer la segunda entrada de datos
	data2, _ := reader.ReadString('\n')
	data2 = data2[:len(data2)-1]

	// TODO: Crear una nueva sesión usando la función NewSession
	// La sesión escapará al heap ya que devolvemos un puntero

	// TODO: Añadir las entradas de datos a la sesión usando el método AddData

	// TODO: Imprimir el resumen de la sesión usando el método Summary
	fmt.Println("")
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos