GC Sweep¶
Implementation in Go 1.23.12: src/runtime/mgcsweep.go
Core Logic¶
The sweep logic itself is simple, but substantial complexity comes from additional requirements:
Additional logic includes: - Bit operations - Arena logic - Special object handling (profilers & finalizers) - Trace logic setup - Internal debug checks - Zombie checks (related to internal logic)
Mark Phase Bit Flip¶
Sweep depends heavily on scan and mark phases. Mark essentially performs bit operations on spans for sweep's use. This bitflip achieves O(1) complexity with no explicit cleanup (actual cleanup happens lazily during allocation).
s.allocBits = s.gcmarkBits
s.gcmarkBits = newMarkBits(uintptr(s.nelems))
atomic.Store(&s.sweepgen, sweepgen)
Span Classification¶
The bit flip operation globally tells runtime which mspans are still in use and which are free. More importantly, spans with modified state need to be returned to memory allocation pools.
Spans are categorized into small objects and large objects (if spc.sizeclass() != 0), each with statistics and return logic.
Small Objects¶
Statistics phase: - Check if any objects within span were freed, mark s.needzero = 1 (CPU resets during allocation) - Update runtime memstats
Return phase: - All objects dead: return to global heap via mheap_.freeSpan(s) - All objects live: push to fullSwept queue: mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s) - Partial liveness: push to partialSwept queue: mheap_.central[spc].mcentral.partialSwept(sweepgen).push(s)
Large Objects (>32KB)¶
Since one span holds one large object: - Dead: return via mheap_.freeSpan(s) - Live: push to fullSwept queue: mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
Sweep Phase Characteristics¶
The sweep phase is lightweight—it mainly performs bit operations and returns spans to the heap.
Note: After sweeping, spans are pushed to heap queues. Pop happens during allocation when allocator grabs an mspan from appropriate queues. In the next GC cycle, spans are scanned and returned to appropriate places.
TODO¶
- TODO: Sweep Termination STW
- TODO: Lazy Sweep impact on allocation latency
- TODO: Sweep Assist and Pacing
- TODO: Manual GC interaction with Sweep