Understanding Go (Golang) Memory Allocation and Management in Go 1.12.6
This article examines Go's memory allocation mechanisms in version 1.12.6, detailing the roles of spans, mcache, mcentral, and mheap, explaining tiny, small, and large object handling, and describing GC and heap reclamation improvements for efficient runtime performance.
Go, released by Google in 2009, has evolved to version 1.12.6 and provides a memory management system optimized for multi‑processor environments, offering C‑like speed while ensuring safety and parallelism.
The runtime implements its own allocator and garbage collector, avoiding frequent OS syscalls and improving performance. This article focuses on the memory allocation behavior of Go 1.12.6.
Basic concepts
A span is the fundamental unit of Go's memory manager; each span handles a fixed‑size class of objects (measured in pages). The mspan structure contains fields such as startAddr , freeindex , allocCache , allocBits and gcmarkBits that track allocation and GC state.
Spans are classified by spanclass , of which there are 67 size classes (see go1.12.6/src/runtime/sizeclasses.go ). The table lists class ID, bytes per object, bytes per span, number of objects, waste, etc., enabling the allocator to pick the most space‑efficient class.
Memory‑management components
The allocator consists of three cooperating components:
mcache – a per‑P cache that holds spans for fast allocation. Its alloc array stores pointers to spans for each size class, separating pointer and non‑pointer objects to avoid unnecessary scanning during GC.
mcentral – a global pool for each size class, protected by a lock. When an mcache runs out of spans, it requests new spans from the corresponding mcentral .
mheap – the underlying heap that obtains memory from the OS, organizes it into arenas, bitmaps, and span tables. It tracks free and used pages, and its heapArena structure defines the layout of virtual memory.
For tiny objects (< 16 B) Go uses a special tiny allocator; for small objects (≤ 32 KB) it allocates from the appropriate span class; for large objects (> 32 KB) it allocates directly from mheap using a global lock.
Allocation rules
Tiny objects: allocate from mcache.tiny , fall back to mcentral , then mheap , finally the OS.
Small objects: allocate from the thread‑local mcache , request new spans from mcentral if needed, otherwise from mheap or the OS.
Large objects: allocate directly from mheap (spanclass = 0) or the OS.
Flow diagrams in the original article illustrate these paths.
GC and heap reclamation improvements (Go 1.12)
The runtime adds reclaimCredit to mheap so that when mcentral requests new pages, the heap first reclaims garbage from existing arenas, storing any surplus credit for future scans. Similarly, scavengeCredit allows the heap to release unused memory back to the OS while keeping credit for later reuse, preventing rapid heap growth and excessive GC pauses.
Conclusion
The article provides a high‑level walkthrough of Go's memory allocation pipeline, linking source files such as go1.12.6/src/runtime/mheap.go , go1.12.6/src/runtime/mcache.go , and go1.12.6/src/runtime/mcentral.go to the described components. Readers are encouraged to explore the source for deeper details.
Xueersi Online School Tech Team
The Xueersi Online School Tech Team, dedicated to innovating and promoting internet education technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.