Gestión de memoria en V en la práctica: GC Boehm, autofree, -gc none y arenas

En el primer artículo de esta serie vimos la sintaxis básica de V. Toca ahora el terreno más resbaladizo del lenguaje: la gestión de memoria, que es también el punto donde más se separa el marketing de la realidad. Ya lo contamos con detalle en la noticia sobre la versión 0.5.1: V se anuncia como un lenguaje «sin recolector de basura», pero por defecto usa uno. Aquí vamos a ver, con código, las cuatro formas reales de gestionar memoria en V y cuándo tiene sentido cada una.

El modo por defecto: GC de rastreo (Boehm GC)

Si compilas un programa V sin ningún flag especial, la memoria se gestiona con un recolector de basura de rastreo basado en Boehm GC. No hay que hacer nada para activarlo, viene incluido:

struct User {
    name string
    age  int
}

fn new_user(name string, age int) &User {
    return &User{ name: name, age: age } // se libera solo cuando el GC decide hacerlo
}

fn main() {
    for i in 0 .. 1000000 {
        u := new_user('user_${i}', i)
        println(u.name)
    }
}

Es el equivalente más cercano a lo que ya conoces si vienes de Go: no piensas en quién libera cada asignación, el runtime se encarga. La diferencia es que el GC de V es deliberadamente minimalista, pensado para molestar lo menos posible, no para competir en sofisticación con el de Go o la JVM.

Modo manual: -gc none

Compilando con v -gc none programa.v desactivas el recolector por completo. A partir de ahí, la memoria que reservas con malloc o structs en el heap hay que liberarla a mano, igual que en C:

import strings

fn build_report() string {
    mut sb := strings.new_builder(1024)
    defer { unsafe { sb.free() } }

    sb.write_string('Reporte generadon')
    sb.write_string('Fecha: 2026-07-04n')
    return sb.str()
}

Es el modo que tiene sentido para sistemas embebidos o cuando quieres control total sobre la latencia, pero asume toda la responsabilidad manual que V dice querer evitarte por defecto.

El modo que sostiene el eslogan: autofree

Aquí está la pieza que más confusión genera. Con el flag -autofree, el compilador analiza el código en tiempo de compilación e inserta llamadas a free() automáticamente, sin necesidad de un recolector en tiempo de ejecución:

v -autofree programa.v

Suena a la solución ideal, pero la documentación oficial de V es tajante al respecto: «Autofree sigue siendo un trabajo en curso. Hasta que se estabilice y se convierta en el valor por defecto, evita usarlo». La propia web reconoce una cobertura de «aproximadamente 90-100%» de los objetos, y pruebas independientes con Valgrind han encontrado fugas reales con estructuras, punteros colgantes y desreferencias nulas en autofree. El roadmap del proyecto en GitHub tiene «gestión de memoria autofree lista para producción» como uno de los objetivos pendientes para la versión 1.0, sin fecha comprometida. Tenlo en producción bajo tu responsabilidad, o mejor, no lo tengas todavía.

Arenas: reserva por bloques

El cuarto modo, con -prealloc, reserva memoria en bloques grandes de una vez y la libera entera al final, sin llevar cuentas individuales de cada asignación:

v -prealloc programa.v

Tiene sentido en programas de vida corta: un script que procesa un fichero y termina, un handler de una petición HTTP que vive milisegundos. Reservas de golpe, trabajas, y tiras todo el bloque cuando acabas, sin el coste de ir liberando trocito a trocito.

¿Qué modo usar?

Para la mayoría de proyectos, el GC por defecto es la opción sensata: es el único de los cuatro modos que V considera maduro. Si necesitas control fino y sabes lo que haces, -gc none te da lo mismo que tendrías en C, con los mismos riesgos. Autofree es una promesa interesante que todavía no ha cuajado, y las arenas son una optimización de nicho para casos muy concretos.

Merece la pena comparar este enfoque con otros lenguajes que también prometen prescindir del recolector de basura: en Zig, la gestión de memoria sin GC no es una opción entre varias sino la única forma de trabajar, con allocators explícitos en cada función que los necesita. Y si prefieres ver cómo se hace en C puro, con las herramientas para cazar fugas, tenemos esta guía de gestión de memoria en C con Valgrind. En el próximo artículo de la serie veremos cómo V maneja los errores sin excepciones, con Option, Result y el operador or.

Imagen: Pexels / Al Nahian

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP