Live data from Hacker News

Go does not need a Java-style GC

erik-engheim.medium.com

181–190 of 226 posts

Re: Go does not need a Java-style GC

#181
post #73

Earlier quoted context omitted.

However it's a weak one, the stack allocation acts as a form of extremely limited nursery, but lots of "escaping" objects could well fit into a nursery, to say nothing of "heap" objects (like strings and slices) which always trigger heap allocations. Furthermore AFAIK most generational GCs have 3 generations, not 2 (let alone 1.5). It does make the tradeoff more complicated, a generational GC is not simple (especiall…

> Go users have to work around using ugly hacks when hit, because they don't have tuning knobs Yeah, Java users just have to hire Java performance tuning experts from sprawling Java perf consulting cottage industry. Can't get much simpler than that.

That's because Java is used to run huge systems (dare I say, "enterprise scale"), whereas golang, especially today with microservices" is not seen in such areas.

However, we still see issues in golang like

* https://blog.discord.com/why-discord-is-switching-from-go-to...

* https://news.ycombinator.com/item?id=21670110

Re: Go does not need a Java-style GC

#182
post #140

Earlier quoted context omitted.

The innovation in WASM is more about getting all the major players in the browser space to agree and support it as a first-class citizen in the web stack. That polyglot bytecodes existed in the early 1980's does nothing for the web.

What a perfect example, have you even tried Java? I'm guessing you are coding for the client? C++ arrogance is the problem here. About the pipe dream of WASM there are 3 problems: 1) Compile times (both WASM and the browser) 2) If you thought Applets where insecure (btw they wheren't) wait until the .js (also a VM with GC...) bindings that you are forced to go through to reach anything from WASM securely gets attenti…

1) No one was realistically compiling C++ or Python to Java though. WASM is not new tech as the other poster said — it’s people coming together to support one compile target that also works on the web, which itself is the crowning achievement.

2) Building a secure VM is easy. You only need to give it access to things it should have access to. If a VM has only math instructions, it’s not going to access the file system. My computer can’t poke my nose because there is literally no machine instruction for it.

Java did not build its VM that way. Instead, the JVM had full access to everything and individual functions were blacklisted within Java applications and this was enforced by Java code running in the same machine as the attacker’s code. Naturally every blacklist works like a sieve.

Re: Go does not need a Java-style GC

#183

The binary-trees benchmark on The Debian Language Shootout[1] involves allocating millions of short-lived trees and traversing them. It is informative about GC performance even with the caveat that there are 'lies, damned lies, and benchmarks', because many real-world graph analysis and brute force tree search algorithms similarly allocate zillions of short-lived nodes. For non-GC languages like C/C++/Rust it gives a…

Look at the Go benchmark program: https://benchmarksgame-team.pages.debian.net/benchmarksgame/... Needs to be faster? Use a pool like the C benchmark programs, but super simple: just a slice, local to the goroutine. Trivially make the Go program 10x faster, 5 minutes of work, a few edits: type Tree struct { Left int Right int } func itemCheck(id int, pool []Tree) uint32 { tree := &pool[id] if tree.Left != -1 && tree.…

Now do the same in Java and it will be as fast, if not faster. The point is the benchmark is looking at GC performance. In large real world programs, it is not trivial to make such changes.

Re: Go does not need a Java-style GC

#184

Earlier quoted context omitted.

The JIT is getting better. Major escape analysis upgrades are a big part of where Graal (a drop-in replacement for the HotSpot JIT) gets its performance boosts. EA definitely does work well there because Truffle depends on escape analysis and scalar replacement very heavily. GraalVM CE is better than regular HotSpot at doing it and GraalVM EE is even better again.

Graal effort is over 10 years old. Jaotc, — Graal's sole mainstreamed part, — has been recently removed from OpenJDK in 17th release, and Oracle says [1], that they are "considering the possibility of using C2 for ahead-of-time" 1: https://mail.openjdk.java.net/pipermail/discuss/2020-Novembe...

It’s almost as if graal and openjdk are separate projects with different use cases. Also, they are not competing (in the usual meaning) since both are developed by Oracle.

Re: Go does not need a Java-style GC

#185
post #140

Earlier quoted context omitted.

What a perfect example, have you even tried Java? I'm guessing you are coding for the client? C++ arrogance is the problem here. About the pipe dream of WASM there are 3 problems: 1) Compile times (both WASM and the browser) 2) If you thought Applets where insecure (btw they wheren't) wait until the .js (also a VM with GC...) bindings that you are forced to go through to reach anything from WASM securely gets attenti…

1) No one was realistically compiling C++ or Python to Java though. WASM is not new tech as the other poster said — it’s people coming together to support one compile target that also works on the web, which itself is the crowning achievement. 2) Building a secure VM is easy. You only need to give it access to things it should have access to. If a VM has only math instructions, it’s not going to access the file syste…

When I think about it, the memory security is probably the weakest point of WASM and probably also the reason nothing of value has come out of that initiative yet.

How does WASM protect memory?

Or maybe there is something valuable made in WASM and I don't know about it, Figma is I think, but I'm not in the target audience.

Re: Go does not need a Java-style GC

#186
post #175
post #135

Earlier quoted context omitted.

Comparing apples to oranges. Java has been around for multiple decades so there may be some bias on your part based on very old examples, but also, your “average” java program is more likely much more complex and larger code base than your average go one. Also, shitty code does get written by developers quite often, regardless of language — at that point the runtime can only do that much.

this is entirely BS. if by complex you mean overly abstracted and useless boilerplate then yes. java is larger and more complex. and your assertion about the runtime only being able to do so much is just wrong here. golang will slow down your application in order to meet GC deadlines. however its incredibly rare to see GC STW pauses for longer than 10s of ms. not even sure its possible given how the GC is written. th…

Have you followed this very thread?

> golang will slow down your application in order to meet GC deadlines

Hardly a good thing for throughput-oriented applications. Java let’s you tune this (the default G1 collector has a target pause time parameter, and then there is also the two new low-latency GC, Shenandoah and ZGC which has > golang entirely sidesteps the issues java has requiring said systems with better memory layouts and utilizing the stack.

As mentioned many times, having value types greatly decreases the amount of created garbage, thus a less-modern GC can be enough for most Go applications. But there absolutely are use-cases where new object creation is unavoidable and java will beat Go by a huge margin, due to its more advanced GC, see:

https://news.ycombinator.com/item?id=29323468

Re: Go does not need a Java-style GC

#187

Earlier quoted context omitted.

Scalar replacement does not work even in very trivial cases: https://pkolaczk.github.io/overhead-of-optional/ In all those cases, Optionals were inlined, didn't escape, yet they haven't been properly optimized out.

Did you understand why?

I don't know the exact reason here, but from my experience JVMs don't seem to perform optimisations as deep as static compilers. You can see the compiler not only missed scalar replacement here, but also didn't use a conditional move to avoid branching neither it performed any loop unrolling. Maybe it is because JITs are constrained by time and resources a lot more.

Re: Go does not need a Java-style GC

#188

Skimmed this and found that a lot of claims are inaccurate and don't have data... Then realized, ugh, it's another Medium post. One particular wrong claim: > In C#, for example, reference objects and value objects live entirely separate lives. Value objects are always passed by value. You cannot take the the address of a value object and pass that around. No, you need to copy the whole object every time. In C#, there…

Yep. His claims about C# are so egregiously wrong that the entire piece can safely be dismissed.

Re: Go does not need a Java-style GC

#189

Earlier quoted context omitted.

Did you understand why?

I don't know the exact reason here, but from my experience JVMs don't seem to perform optimisations as deep as static compilers. You can see the compiler not only missed scalar replacement here, but also didn't use a conditional move to avoid branching neither it performed any loop unrolling. Maybe it is because JITs are constrained by time and resources a lot more.

It'd be worth doing a deep dive into this - you can look at the compiler's intermediate representation to understand why it didn't make an optimisation. There may be something trivial getting in the way.

Re: Go does not need a Java-style GC

#190

This is mostly stupid. Being able to have many GCs is a good thing. The big reason for "value types" is controlling spacial locality in memory, not GCs being bad per-se. Also, they undersell the java/c# situation. C# has "ref, out, or in", but even without those, you can always make a reference wrapper that has the value type as a field. So "reference types suck because coppying" is nonsense garbage.

I mean, I’ve dabbled in all of these languages, and I much prefer Go’s value types to ref, out, in, and a half dozen GCs. It’s nice that these VM languages have a distinct thing for every eventuality, but I much prefer a single thing that works 99% of the time.

Why do you much prefer

  func changeName(p *Person) {
    p.firstName = "Bob"
  }
to

  void changeName(ref Person p) {
    p.firstName = "Bob";
  }

?
Post reply on HN