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 gestiona la memoria automáticamente mediante la recolección de basura (GC). No necesitas liberar manualmente la memoria cuando terminas de usarla. El entorno de ejecución de Go realiza un seguimiento de la memoria que todavía está en uso y recupera el resto.

Cuando asignas memoria mediante new(), make() o al crear variables, el recolector de basura de Go supervisa estas asignaciones. Una vez que un valor deja de ser accesible desde cualquier 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 usa, el GC recupera la memoria
}

En este ejemplo, la estructura Person se asigna en el montón 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 la pila o debe pasar al montón. El recolector de basura solo administra la memoria del montón.

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

challenge icon

Desafío

Fácil

Construyamos un administrador de sesiones que demuestre cómo el recolector de basura de Go gestiona la memoria de los objetos que escapan al montón. 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 campos ID (string), Username (string) y Data (una slice de strings). Crea una función NewSession que reciba un ID y un nombre de usuario, asigne una nueva Session en el montón (al devolver un puntero) e inicialice la slice Data como vacía. Añade también un método AddData con un receptor puntero que agregue un string a la slice Data de la sesión, y un método Summary que devuelva un string formateado con 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, agrégale algunas entradas de datos y muestra el resumen de la sesión. Como la sesión se crea dentro de una función y se devuelve como puntero, escapa al montón, donde el recolector de basura la gestionará.

Se proporcionarán las siguientes entradas:

  • Línea 1: ID de la sesión
  • Línea 2: Nombre de usuario
  • Línea 3: Primera entrada de datos que se agregará
  • Línea 4: Segunda entrada de datos que se agregará

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 montón en lugar de permanecer en la pila, por lo que puede ser recolectada por el recolector de basura cuando ya no queden referencias a ella. Tu código no necesita liberar esta memoria manualmente: Go lo gestiona automáticamente.

Pruébalo tú mismo

package main

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

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

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

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

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

	// Leer 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

Practica por tu cuenta: Compilador de Go online