Go: How Does the Garbage Collector Mark the Memory?
ℹ️ This article is based on Go 1.13. The notions about memory management discussed here are explained in my article “Go: Memory Management and Allocation.”
The Go garbage collector is responsible for collecting the memory that is not in use anymore. The implemented algorithm is a concurrent tri-color mark and sweep collector. In this article, we will see in detail the marking phase, along with the usage of the different colors.
You can find more information about the different types of garbage collector in “Visualizing Garbage Collection Algorithms” by Ken Fox.
This phase performs a scan of the memory to know which blocks are still in use by our code and which ones should be collected.
However, since the garbage collector can run concurrently with our Go program, it needs a way to detect potential changes in the memory while scanning. To tackle that potential issue, an algorithm of write barrier is implemented and will allow Go to track any pointer changes. The only condition to enable write barriers is to stop the program for a short time, also called “Stop the World”:
Go also starts, at the beginning of the process, a marking worker per processor that help with marking the memory.
Then, once the roots have been enqueued for processing, the marking phase can start traversing and coloring the memory.
Let’s now take an example with a simple program that will allow us to follow the steps done during the marking phase:
Since the struct
subStruct does not contain any pointer, it is stored in a span dedicated to objects with no reference to other objects: