3 min read | by Jordi Prats
In Golang, there are two environment variables that can be used to manage the Garbage Collector in Go: GOGC
and GOMEMLIMIT
. With these variables, you can control how often the garbage collector runs and set an overall memory limit that the Go runtime can use.
To fully understand how to setup the GOGC
and GOMEMLIMIT
environment variables, it's important to understand how the garbage collector works in Go and it's terminology.
The Go garbage collector is responsible for managing memory allocation and recycling in the heap. The heap is home to dynamically generated objects such as structs, slices, maps, and substantial memory blocks that cannot fit within the stack's constraints. The garbage collector is the tool that it is in change of recycling heap memory and preventing it from growing indefinitely.
From the garbage collector's perspective, the heap memory is divided into two categories: live heap memory and new heap memory:
After the garbage collector identifies some unused memory, it reclaims it and makes it available for new memory allocations.
The GOGC
parameter dictates the percentage of new, unallocated heap memory concerning live memory at which garbage collection initiates. By default, it is set to 100
, meaning that garbage collection triggers when the amount of new memory reaches the same amount as the live heap memory.
We can set this value to a lower percertage to trigger the garbage collector more frequently, or to a higher percentage to trigger it less often.
There's a special value for GOGC
: off. This value disables triggering the garbage collector due to heap growth.
Starting from Go version 1.19, Golang introduced "soft memory management" with the GOMEMLIMIT
option. This feature uses the GOMEMLIMIT
environment variable to set an overall memory limit that the Go runtime can use.
GOMEMLIMIT
can be a double-edged tool: When the overall memory size approaches the GOMEMLIMIT
the garbage collector might be constantly triggered, leading to increased CPU usage and decreased program performance. Unlike a OOM error, this can be really tricky to detect and fix.
It is worth mentioning that GOMEMLIMIT
doesn't provide a guarantee that the memory limit will be strictly enforced, allowing memory utilization beyond the limit.
It might be very tempting to set GOGC=off
and GOMEMLIMIT
to the actual memory limit of the system. We need to keep in mind that the garbage collector is a crucial part of the Go runtime and it's there to keep the memory usage under control: By disabling it and only letting it run when it reaches the memory limit, instead of running small garbage collections, we might end up with a huge garbage collection cycle that will affect the performance of the application.
Posted on 05/11/2024