I would wager that Java's GC is better just for the simple fact that it has a whole bunch of knobs you can turn based on your workload. I've investigate an issue with a very time Go program, and the performance of it was being harmed by the Garbage Collector.~600ns GC doing 2k GC/s per second- ~12% of its time was spent garbage collecting. The solution was to turn the GOGC to 37- this yielded the best results but only increased performance 5%.
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.
I would guess the same. Go's GC is narrowly tuned towards server workloads with pretty low latency. That means batched workloads (such as the Go compiler itself!) is hurt by GC.
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.
“At least has a jit”, go is compiling to native code, Java is to a jvm bytecode instruction executed effectively by a interpreter, a jit is critical to good performance in the latter. In the former, ie. go you have control over memory layout and are already in machine code at execution the constructs of the language aka runtime are effectively a linked library instead of a virtual machine.
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
> I would wager that Java's GC is better just for the simple fact that it has a whole bunch of knobs you can turn based on your workload.
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)
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.
reply