Skip to content

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

Further Reading