Home
Nov 11, 2025

Very Basic Overview of Go Garbage Collector

golanggarbage-collectionruntimememory-management

This note is a very basic introduction to how garbage collection works in Go, just enough to build an intuition. I plan to write a more in-depth and technical article after reading the official Go Garbage Collector Guide.

What Triggers the Garbage Collector in Go

The Go runtime automatically decides when to run the garbage collector based on:

  • Memory pressure (how much heap memory is currently used)
  • Allocation rate (how quickly the program is creating new objects)

How It Works

  • The GC runs concurrently with the program, so it doesn’t completely pause execution.
  • It’s typically triggered when the heap grows beyond a certain threshold.
  • The Go runtime monitors allocations and schedules the GC adaptively.

Manual Trigger

We can also trigger garbage collection manually in Go mainly for testing:

1import "runtime"
2
3func main() {
4    runtime.GC()
5}

This forces an immediate GC cycle. The Go garbage collector’s adaptive scheduling means you don’t need to manage memory manually, but understanding when and why it runs can be useful!

Example: What Happens in Memory

Consider the following Go program:

 1package main
 2
 3var global *int
 4
 5func main() {
 6    f()
 7}
 8
 9func f() {
10    a := 42
11    b := 52
12    global = &a
13}

Before f() Returns

  • Each function has its own stack frame.
  • Inside f(), both a and b are local variables on the stack.
  • When we assign global = &a, the compiler detects that a escapes to the heap.

So the memory looks roughly like this:

1main()
2 └── f() stack frame
3      ├── a = 42  (moved to heap because of escape)
4      └── b = 52  (on stack, disappears after f() returns)
5global → points to a (on heap)

After f() Returns

  • The stack frame of f() is gone, so b is gone.
  • a stays in the heap because it’s still reachable through global.
  • When the garbage collector runs, it starts from roots (like global) and follows all reachable objects.

Only a is marked as reachable, and everything else not connected to a root can be safely reclaimed.