← Back to context

Comment by deepsun

5 days ago

Are you sure about Go's garbage collector doesn't have pauses? AFAIK they are worse than modern Java's garbage collector [1].

I'm not sure it's even better than Java's, especially for modern ZGC (and you can choose your GC in Java). Definitely less configurable. I would say most of online comments about Java's GC are long outdated.

For example, in web servers a lot of work is request-response, so it's convenient to utilize generational GCs (so that each request data would fit into "young" generation). Similar to arenas, but without code changes. Go's GC is not generational though, so you should care about allocations.

https://codemia.io/blog/path/The-Evolution-of-Garbage-Collec...

> I would say most of online comments about Java's GC are long outdated.

They are not. Feel free to look up literally any half-decent benchmarks. If Java's on par or better than any other language of note, check the memory usage. It's standard for Java to have 5-20x the memory usage for about the same performance. The memory floor also seems to be in the hundreds of megabytes. Ridiculous.

> For example, in web servers a lot of work is request-response, so it's convenient to utilize generational GCs (so that each request data would fit into "young" generation).

No, that's a job for arenas. Generational GCs are mostly a result of Java's limitations, and not a univerally good approach.

> Go's GC is not generational though, so you should care about allocations.

You should always care about allocations. In fact, the idea that you shouldn't is a big part of Java's poor performance and design.

  • No-one ever claimed that Java didn't use a lot of memory. The "comments about Java's GC" used to be about pauses, mainly. Java programmers don't claim that the JVM is conservative with memory use. That said, 5-20x.... nah. Maybe for a toy 'hello world' sized program, but not in real usage

Java's GCs (plural) are hands down better.

  • Hell, I even had a use case where serial GC was actually the correct choice (small job runner process that needed to be extremely low memory overhead). It's nice having options, and most of those options are extremely good for the use cases they were designed for.

  • Ok, which one do I choose then, with what configuration? How much time do I need to spend on this research?

    How do I verify that they are actually better? Is the overall performance of my program better? Because that's what I care about. I of course do include memory usage in "performance".

    • Do you need extra-low latency, even at very high percentile and are willing to give away a bit of throughput for it? ZGC

      At almost every other case: G1 (the default, just don't add any flags).

      Do you want to trade off using less memory at the price of some throughput? Decrease heap size, otherwise don't add anything.

      That's it, in most cases just use the default.