Go: Under the Hood Under the Hood
中文

Chapter 13 Garbage Collector

When is the best time to do a GC? When nobody is looking. Using camera to track eye movement when subject looks away do a GC.
-- Rick Hudson, "Go GC: Latency Problem Solved", 2015

In his GopherCon 2015 talk, Hudson posed this question right after the slide that named GC latency as the main obstacle. After the joke, the next two slides gave two other answers: pop up a spinning icon while waiting on the network, or trade throughput for lower GC latency. Go 1.5 chose the last one: the collector runs concurrently with the program and takes a share of CPU time in exchange for shorter pauses (13.12.2). Over the following decade the collector’s evolution has largely revolved around the same problem: how to strike a better balance among pause time, CPU overhead and memory footprint.

This chapter examines how Go’s collector makes that trade. 13.1 introduces reachability, mark-sweep and the tricolor abstraction, and places Go among the kinds of collectors. 13.2 covers the write barrier that concurrent marking requires, and the hybrid write barrier Go adopted. 13.3 through 13.7 follow the stages of one collection cycle: how the pacer uses GOGC and the soft memory limit to decide when to start a cycle, how mark workers and mark assists share the marking work, how sweeping reclaims dead objects, how the mark termination phase decides that marking is complete, and how the collector uses stack maps to find pointers on stacks. 13.8 and 13.9 cover two designs that were tried and not adopted, generational collection and request-oriented collection. 13.10 covers finalizers, cleanup functions and weak pointers. 13.11 covers Green Tea, enabled by default since Go 1.26. 13.12 reviews the collector’s evolution in chronological order, and 13.13 revisits Go’s collector through the unified theory of tracing and reference counting. For how objects are allocated, see Chapter 12.