Memory Management
Memory Management
Go automatically manages memory with its Garbage Collector.
Most of variables allocation definition is done at compile time. But they can be moved in certain circunstances at runtime.
Check escape analysis and heap allocation by running go build -gcflags '-m'.
Tips for better performance
Don't always use pointers in parameters to pass values like structs, to avoid memory duplication. (Target pointers to > 64 bytes structs, or if used in multiple functions)
Prefer Stack allocation when possible.
Stack
Used for small, local, short-lived, and that do not escape the function variables.
Automatically cleaned up when function exits. (That's why short-lived)
Variables allocated in the Stack, can be moved at runtime to the heap if they escape their initial scope.
They will be in the Stack or stay there if no conditions to go to the Heap are met.
Heap
Used for large or long-lived variables (slower, garbage-collected)
They live until garbage collected. (That's why long-lived)
A closure captures a variable
func() { x++ }
The variable outlives the function
Returning a pointer to a local variable
return &x
The local variable must persist
Structs stored in an interface
var i interface{} = MyStruct{}
Interfaces store references
Large arrays/slices (Maps always)
make([]int, 100000)
Avoids stack overflow
Structs passed by reference
func test(p *Person){}
Explicit heap allocation
General rules for Arrays/Maps/Slices
themselves (the slice header: pointer, length, capacity) is allocated in the Stack.
But its underlying Array is in the Heap IF they are large.
are always allocated in the Heap, because internally, it contains a pointer to a hash table, which lives in the heap.
Memory Leaks
Monitor memory leaks using pprof (Go's profiling tool)
Usually happen when Heap memory isn't freed properly.
Global variables holding large data
Avoid unnecessary global variables
Unclosed Goroutines
Use sync.WaitGroup or context.Context to stop them
Slices growing without limit
Use make() with a sensible capacity
Forgotten closures holding memory
Set function references to nil when no longer needed
Last updated