Gc
gc forces an immediate garbage collection sweep. gc_mode sets how the VM manages memory automatically.
Overview The Goblin VM uses an arena-backed memory model. Every value lives in a slot called a stash, addressed by a tether. When a tether's reference count reaches zero the stash becomes unreachable. A GC sweep finds and frees all unreachable stashes.
x | "some large value" x |= nil gc() /// stash for the old string is freed GC Modes Three modes control when sweeps happen:
Mode When sweeps run "auto" Automatically every 10,000 allocations. This is the default. "manual" Only when you call gc() explicitly. "off" Never. Values accumulate until the session ends. Switch mode at any point with gc_mode:
gc_mode("manual") /// take control yourself gc_mode("off") /// disable GC entirely gc_mode("auto") /// restore the default gc_mode takes effect immediately. Switching from "off" to "manual" does not trigger a sweep — call gc() when you are ready.
Forcing a Sweep Call gc() to sweep right now, regardless of mode:
gc() This is most useful in "manual" mode, where you decide exactly when to pay the collection cost:
gc_mode("manual") repeat 10000 data | load_big_thing() process(data) data |= nil gc() /// free before the next iteration end Inspecting Memory Four builtins let you observe memory usage:
mem_total() /// process resident memory in bytes mem_human() /// human-readable string, e.g. "6.4 MB" mem_id(x) /// { slot, generation } address of x's stash mem_addr(x) /// hex pointer to x's stash, e.g. "0x7ffd3a20" Example:
gc_mode("manual") x | "hello" :say(mem_human()) /// e.g. "3.1 MB" x |= nil gc() :say(mem_human()) /// e.g. "3.0 MB" mem_total and mem_human report the process resident memory — the working set size of the entire Goblin process, not an internal slot count. The numbers reflect real OS-level memory usage.
mem_id and mem_addr return the real arena address of a specific value's stash — not a simulation. These are useful for verifying identity and debugging aliasing.
Generation Safety Each stash carries a generation counter. When a stash is freed its generation advances. Any tether that still holds the old generation number is considered stale and will not dereference — the VM will error rather than read freed memory.
This means "off" mode is always safe as long as the session is live. It simply keeps all stashes allocated until the session ends.
Signatures gc() gc_mode(mode) mem_total() mem_human() mem_id(value) mem_addr(value) Argument Type Returns Description — — nil gc() forces an immediate sweep mode string nil gc_mode() sets the active GC mode — — integer mem_total() returns process resident memory in bytes — — string mem_human() returns resident memory as a readable string value any map mem_id() returns { slot, generation } value any string mem_addr() returns a hex pointer string Errors gc_mode requires a valid mode string:
gc_mode("fast") /// error: runtime-error: gc_mode: unknown mode 'fast' — use "off", "manual", or "auto" ::: nav next Mem Id previous Format Info :::