SoFunction
Updated on 2025-03-03

A brief discussion on Golang's GC garbage collection mechanism

Preface

In modern programming languages, the Garbage Collection (GC) mechanism is a crucial feature. It helps developers manage memory automatically and avoid problems such as memory leaks and hanging pointers. Go language (Golang) is a modern programming language with an efficient garbage collection mechanism built in. This article will dive into the GC mechanism of Go, explains how it works through code examples, and shows how to optimize code to reduce GC stress.

1. Introduction

o The garbage collector of the language is mainly based on Mark-and-Sweep and Tri-color Marking algorithms. Here are the basic principles of these two algorithms:

Mark-and-Sweep

The mark-clearing algorithm is divided into two stages:

1. Marking stage:Start with the root object (such as global variables, local variables on the stack, etc.), iterate through all reachable objects and mark them as "reachable".
2. Clearing phase:Travel all objects in the heap and recycle those objects that are not marked as "reachable".

Tri-color Marking

The tri-color marking algorithm is an improvement of the mark-cleaning algorithm, mainly used for concurrent garbage collection. It divides objects into three colors:

1. White:Unmarked objects represent unreachable or unchecked objects.
2. Gray:Objects that have been marked but referenced have not been checked.
3. Black:Objects that have been marked and referenced by them have also been checked.

The workflow of the three-color marking algorithm is as follows:

1. Initialization:All objects are white at the beginning.
2. Marking stage

  • Mark the root object grayed out.
  • Processing grey objects: Mark all white objects referenced by the grey object as gray, and mark the current grey object as black.
  • Repeat the above steps until there are no gray objects.

3. Clearing phase:All objects that are not marked as black (i.e., white objects) are unreachable and can be recycled.

2. Code explanation

To better understand the GC mechanism of Go, we demonstrate how it works and optimization methods through a simple code example.

Sample codeHere is a simple Go program that creates a large number of short lifecycle objects:

package main

import (
    "fmt"
    "runtime"
    "time"
)

func createObjects() {
    for i := 0; i < 1000000; i++ {
        obj := make([]byte, 1024) // Create 1KB object        _ = obj
    }
}

func main() {
    var m 

    // Print initial memory usage    (&m)
    ("Initial: Alloc = %v MiB\n",  / 1024 / 1024)

    // Create an object    createObjects()

    // Print the memory usage after creating the object    (&m)
    ("After creation: Alloc = %v MiB\n",  / 1024 / 1024)

    // Forced garbage collection    ()

    // Print the memory usage after garbage collection    (&m)
    ("After GC: Alloc = %v MiB\n",  / 1024 / 1024)

    // Wait for a while to observe memory usage    (5 * )
}

Code explanation

1. Create an object:The createObjects function creates 1 million 1KB objects. These objects are short-lived and are discarded immediately after creation.
2. Memory statistics:Use the function to obtain memory usage and print it out.
3. Forced garbage collection:Use functions to force garbage collection.
4. Observe memory usage:By printing memory usage, memory changes before and after garbage collection can be observed.

3. GC optimization method

1. Use Object Pool

Use to reuse objects and reduce frequent allocation and release. Object pools can significantly reduce the number of allocations for short-lifetime objects, thereby reducing GC stress.
Sample code

var pool = {
    New: func() interface{} {
        return new(MyStruct)
    },
}

func main() {
    for i := 0; i < 1000; i++ {
        obj := ().(*MyStruct)
        // Use obj        (obj)
    }
}

advantage

  • Reduces the allocation and release of short-lifetime objects.
  • Improves memory usage efficiency and reduces GC frequency.

2. Reduce short life cycle objects

Minimize the creation of short-lifetime objects, especially in functions called at high frequency. Unnecessary object allocation can be reduced by optimizing algorithms and data structures.

Sample code

func process() {
    // Avoid frequent creation of temporary objects    var temp MyStruct
    for i := 0; i < 1000; i++ {
        // Use local variables instead of creating new objects every time        temp = MyStruct{}
        // Processing logic    }
}

advantage

  • Reduces the frequency of memory allocation and release.
  • Reduces GC workload and improves program performance.

3. Adjust GC parameters

Adjust the trigger frequency of GC by setting the GOGC environment variable. The default value is 100, indicating that garbage collection is triggered when the heap memory usage grows to 100% of the surviving objects after the last garbage collection. This value can be adjusted as needed.

Sample code

export GOGC=200  # Set the GC trigger frequency to twice the default value

advantage

  • The GC frequency can be flexibly adjusted according to the specific needs of the application.
  • In the case of sufficient memory, the GC trigger frequency can be reduced, thereby improving program performance.

4. Summary

The garbage collection mechanism of Go language is based on the mark-clear and tri-color marking algorithm, which can efficiently manage memory and avoid memory leaks and hanging pointers. However, when dealing with a large number of short life cycle objects, GC pressure may increase significantly. By using object pools, reducing the creation of short life cycle objects, optimizing memory layout, etc., we can effectively reduce GC pressure and improve program performance.

This is the end of this article about a brief discussion of Golang's GC garbage collection mechanism. For more related contents of Golang GC garbage collection mechanism, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!