3 ms·
Good point about Gen0, because Go's GC isn't even generational or compacting so you really do pay for all of these nested and repeated messages in full every ti
by fl0ki 2y ago
Good point about Gen0, because Go's GC isn't even generational or compacting so you really do pay for all of these nested and repeated messages in full every time. At best the allocation is serviced from the thread-local cache, but the deallocation will almost always be done by a separate GC thread that now has to do a ton of fenced loads from main memory.
If the GC fully keeps up, it's all outside your critical path and you don't really notice it. But if it doesn't keep up, then the routines doing the allocation are tasked to assist the GC to catch up, adding up to a 10ms pause in the critical path of the routines actually serving requests. This is quite an exception to the claims that Go's GC is good for low-latency applications, and it's yet another reason to contort the entire schema to minimize heap allocations.
- neonsunset 2y agoInteresting, TIL! .NET's GC has a similarity in allocations being serviced from thread-local allocation context and only ever going into GC when such can't be serviced, when that happens, most workloads using SRV GC, would go into a short stop-the-world pause to collect Gen 0. While STW does sound scary to many, such pauses can be easily sub-millisecond in reality given sufficiently GC-friendly allocation patterns even under full allocation throughput saturation[0]. [0] Made short example that demonstrates that GC just frees up Gen0s as soon as they are full, which is very cheap, even if it has to be done very frequently: https://gist.github.com/neon-sunset/62115b5d9aa5027b22fa00f89e354e30 https://gist.github.com/neon-sunset/62115b5d9aa5027b22fa00f8... (GC used here is the latest SRV GC + DATAS mode which is planned to become default later on, practically speaking, it has little impact under saturation and more interesting under moderate to light allocation rates as it solves the historical issue with SRV GC being quite happy to hoard memory pages from the kernel for a long time even if the actual heapsize was very small)