https://blog.plan99.net/modern-garbage-collection-part-2-1c8...
https://www.reddit.com/r/golang/comments/5j7phw/modern_garba...
> "Go: 67 ms max, 1062 pauses, 23.6 s total pause, 22 ms mean pause, 91 s total runtime
> Java, G1 GC, no tuning: 86 ms max, 65 pauses, 2.7 s total pause, 41 ms mean pause, 20 s total runtime"
What I got from this is that Go has faster GC pauses at the cost of throughput (i.e. more pauses resulting in higher total pause time).
The new JVM Shenandoah GC also makes this tradeoff by adding another layer of indirection ("Brooks forwarding pointer") which has a throughput performance cost but gives you really low GC pauses.
My coworkers were saying how they had 100s of knobs they could turn and try to try and tune the GC to either reduce the number of pauses, or do one big one every 10 seconds. . Java's options are more then I wish to list here. Go has `GOGC=` and that's it.
As one to one performance, that would be hard to measure, but my guess is Java would win in the end.
Tuning the GC is a challenge in and of itself. When you get so many knobs to turn, it can get hard to rationalise the overall impact of any particular one. It's part of why skilled DBAs are worth their weight in gold, for example (there was a fun paper & tool from CMU a couple of years ago, OtterTune https://github.com/cmu-db/ottertune, which tries to apply machine learning to what is almost a black-box optimisation problem)
Here's a nice presentation transcript that summarizes the design decisions behind Go's GC: https://blog.golang.org/ismmkeynote And as you can see, it's basically entirely driven by low latency, but not necessarily high throughout.
Another point to consider besides GC is that Java at least has JIT which really benefits hot paths; Go does not.
Golang prefer one simple way over playing with runtime knobs. That said the gc characteristics of go, are partly reactionary to java at that time (10yrs ago) unpredictable latency and pauses, and they optimized to address that also in response to early prod users. All gc languages have gc overhead from a throughput perspective 15-20% afaics
However, the biggest difference is that there's only one Go GC, while there are several supported ones for Hotspot. With the exception of CMS, which is deprecated, those collectors occupy different niches, meaning there are times you'd use each of them.[0]
The Go collector is optimized for relative simplicity and low latency, and currently tolerates significant overhead to hit that target.
[0] Maybe Shenendoah and ZGC are close enough that they're just direct competitors? Perhaps they're even designed to supercede G1? I'm not quite sure about that, but even so, it would leave at least 2-3 options, depending on whether you include Serial/Epsilon as serious options.
For more, see the excellent blog post here: https://blog.golang.org/ismmkeynote
However, to your point, so far as the languages tend to allocate more or less data on the heap, that might change which benchmarks look good, the same way that you'll care about different automotive benchmarks if you want to tow a trailer or race.