Hacker News new | ask | show | jobs
by brighteyes 2374 days ago
The technical detail in this article is excellent! A great read.

But I think it would have been an even better article without the negativity about Go and how the author thinks "the Java guys are winning" in his words. That felt a little petty.

1 comments

Why? Did he hurt Go's feelings? It's a programming language, not a child. I prefer his honest assessment of their relative strengths and weaknesses.
Except that it isn't necessary nor is it completely honest. Go and Java take different approaches here, but the article focuses on the merits of the Java approach and the downsides of the approach taken by Go.

Example 1. The article talks about compaction and generational collection as being Good Things(TM), but it doesn't talk about the costs associated with them. Looking at the linked Go article, these approaches suffer from high write barrier overhead. For Go, this isn't worthwhile because escape analysis allocates many young objects on the stack (which btw is effectively bump-pointer allocation) so trying to further reduce GC overhead by increasing the overhead of every pointer write is just not worth it. It may, however, be the right trade-off for Java.

Example 2. Java's many tuning parameters means that programmers who care about performance have to choose the right GC and tune it. If better GCs come out or tweaks to the algorithms are made, these configurations have to be updated. In contrast, Go programs gets these benefits for free. The best approach seems to be to offer a small number of high-level knobs, but it's hard to determine what those are, leading to the two (suboptimal) extremes you see with Go and Java.

These are common misconceptions.

> Example 1. The article talks about compaction and generational collection as being Good Things(TM), but it doesn't talk about the costs associated with them. Looking at the linked Go article, these approaches suffer from high write barrier overhead.

You need a write barrier no matter what for any sort of incremental or concurrent GC, to maintain the tricolor invariant. Otherwise there is no way for the runtime system to detect a store from a black object to a white object. Typical GCs will fold the write barrier needed for generational GC into the write barrier needed for incremental/concurrent GC, so there is no need for extra overhead if properly implemented.

> For Go, this isn't worthwhile because escape analysis allocates many young objects on the stack (which btw is effectively bump-pointer allocation)

Java HotSpot has done the same thing for a long time! It's just that in HotSpot escape analysis doesn't really help allocation performance, because the generational GC already offers bump allocation in the nursery. Escape analysis in the JVM does open up more optimizations, though, because it serves as the scalar-replacement-of-aggregates transformation.

> so trying to further reduce GC overhead by increasing the overhead of every pointer write is just not worth it.

This is only because of their specific implementation. There is no need for increased overhead.

> If better GCs come out or tweaks to the algorithms are made, these configurations have to be updated. In contrast, Go programs gets these benefits for free.

There is no reason why Java can't do the same by updating defaults. In fact, they often do.

>> If better GCs come out or tweaks to the algorithms are made, these configurations have to be updated. In contrast, Go programs gets these benefits for free.

> There is no reason why Java can't do the same by updating defaults. In fact, they often do.

Correct. The JVM guys always update the default GC to be the nearest to 'one size fits all'. Obviously if you've made a custom GC configuration then you want a level of tuning that Go does not provide.

Yet another person who only skimmed the article and hasn't read Part 1, which explains GC tuning tradeoffs and addresses the two examples you mentioned. Part 1 debunks the dishonest marketing from Google around Go's GC when it was originally released, and discusses the tradeoffs that weren't disclosed.
I just think our industry would be a better place if we didn't try to tear down other technologies, say stuff like "X sucks", etc.

But I agree that friendly competition is a good thing! I feel this article was a little past that, though.

But he didn't say that. That's your own ridiculous emotional projection. The article contains very thoughtful criticism backed by detailed analysis. I don't think you even bothered to read the full articles (there is a part 1). The final sentence was, "Overall, it looks to me like the Java guys are winning the low latency game.", and that's a fair conclusion.
Based on the facts stated in the article (part 2), it looks like (years later) Java now has a new garbage collector available (ZGC, still labeled experimental, not used by default) [1]. It's an order of magnitude lower latency than current default collector, but it still has an order of magnitude higher latency target (10ms vs 1ms) than Go. I'm sure there are many good reasons for the trade offs made and that's a huge improvement, but in light of the basic numbers I'm not sure that "the Java guys are winning the low latency game" is, in fact, a fair conclusion.

Go introduced a new GC a while back with dramatically lower latency numbers, not only compared to the previous Go GC but any other commonly available GC in any language (excluding exotic commercial ones like Azul). Neither the old or new Go GCs are particularly sophisticated compared to the highly developed ones in the Java ecosystem.

The author of these articles seems to take objection that the latency numbers were achieved not by magic or pure GC implementation genius but by simply optimizing for latency, which involves some trade offs. I don't think this negates the usefulness of having a low latency GC available though, although I can understand how it might be frustrating to see a project getting a lot of attention for what feels like a lesser intellectual achievement.

Obviously not all projects even require low worst-case latency, monolithic apps will be less sensitive, applications waiting on 10 other services will be more etc. Some apps the CPU isn't a bottleneck either. It's just another trade off where Go is prioritizing some things. There's even other factors not mentioned in the article like a compacting collector might make calling C functions more complex since it needs object pinning.

[1] There's also another GC mentioned that's less talked about in the article, Shenandoah, that requires patching the JVM and introduces memory overhead to every object for a forwarding pointer. It was hard to find numbers, but it looks like the latency target for this GC is also in the 10ms range (http://clojure-goes-fast.com/blog/shenandoah-in-production/).

> It's an order of magnitude lower latency than current default collector

Believe it or not, the current default GC is G1GC, which has a target (and quite common) pause of 300ms by default.

> Go introduced a new GC a while back with dramatically lower latency numbers

Or maybe just like Azul's numbers from 2005?

http://big-elephants.com/2018-09/unexpected-gc-pauses/

https://www.usenix.net/legacy/events/vee05/full_papers/p46-c...

> Shenandoah, that requires patching the JVM

The page you linked to says "How do you get Shenandoah? This garbage collector has officially become part of JDK only since version 12 and is available in AdoptOpenJDK 12 builds."

> and introduces memory overhead to every object for a forwarding pointer.

The first version did, Shenandoah 2.0 does not

https://shipilev.net/talks/jugbb-Sep2019-shenandoah.pdf

> Or maybe just like Azul's numbers from 2005?

In the very sentence you quoted I said “excluding exotic commercial ones like Azul“. I’m not sure what point you are trying to make here.

> Shenandoah 2.0 does not

I see. I only googled that link to find the latency target (since it wasn’t mentioned in the original article), I have to confess I didn’t read the rest of it and almost all of what I wrote is based on the original article. Good to know that some of that information is now out of date.

Maybe you're right, I might be too sensitive on this matter. Thank you for your thoughts.
I am always right. Go sucks and Java wins. (just kidding)
Half right, anyway.