Hacker News 上看到「How We Saved 70K Cores Across 30 Mission-Critical Services (Large-Scale, Semi-Automated Go GC Tuning @Uber)」這篇,講 Uber 的人怎麼調整 Golang 的 GC,在 Hacker News 上的討論「Large-scale, semi-automated Go GC tuning (uber.com)」也有些東西再講。
一開始的方法是動態一直調整 GOGC
的值:
Our initial approach was to have a ticker to run every second to monitor the heap metrics, and then adjust GOGC value accordingly.
但這個方法的 overhead 太重:
The disadvantage of this approach is that the overhead starts to become considerable, because in order to read heap metrics Go needs to do a STW (ReadMemStats) and it is somewhat inaccurate, because we can have more than one garbage collection per second.
後來的方法是利用 SetFinalizer
來做 (然後這段 code 不知道為什麼是用圖片...):
Luckily we were able to find a good alternative. Go has finalizers (SetFinalizer), which are functions that run when the object is going to be garbage collected. They are mainly useful for cleaning memory in C code or some other resources. We were able to employ a self-referencing finalizer that resets itself on every GC invocation. This allows us to reduce any CPU overhead.
不過 Hacker News 上有些人也很驚訝於 30 個 service 用掉 70K cores 這件事情,以 Uber 的服務來說算是比預想多不少數字,而且這只是跑 Golang,而且這次省下來的部份...
另外在 Hacker News 上也有人提到 Golang 有在思考 soft memory limit 的設計,也值得看一看:「runtime/debug: soft memory limit #48409」、「Proposal: Soft memory limit」。