Live data from Hacker News

Go does not need a Java-style GC

erik-engheim.medium.com

81–90 of 226 posts

Re: Go does not need a Java-style GC

#81
post #56

Earlier quoted context omitted.

FWIW. This would probably present a challenge in most (all?) languages. For example in libc++ due to SSO an std::string has a minimum size of 24 bytes. For a billion strings less than 15 chars (+ the null byte) that gets you to 24GB, and that’s optimistically assuming each string is allocated in place. I doubt heap allocated char* would do much better either. Just having a billion 8 byte pointers eats a lot of memory…

It's a lot easier to build custom allocators in C++ though. For one, Java has a maximum mmap-size of 2 Gb, and as a cherry on top of that turd, you have no control over their lifecycle. The language is very clearly not designed for this type of work, and if you try to make it do it anyway, it fights you every step of the way.

The foreign memory API which is currently incubating should help with most of these limitations: https://openjdk.java.net/jeps/419

Re: Go does not need a Java-style GC

#82

I'm cautious about believing this sort of claim because I remember reading about why Go doesn't need generics, yet here we are waiting for Go Generics to be ready. However, the article convincingly explains who Java has a greater need for a compacting GC - it creates more garbage. This doesn't necessarily mean Go won't benefit from having a generational, compacting GC at some point, for some applications.

Even if it doesn't need specifically a compacting QC having a swappable more tunable one might still be a big deal for people who need something other than the current GC. Like a simple example is the Discord article about how their use case could not work with Go because it always ran the GC every two minutes. If they could optionally disable that feature they theoretically could have kept using Go instead of rewrit…

That wasn't my read.

The Discord team that wrote the article I believe you're referencing ( https://discord.com/blog/why-discord-is-switching-from-go-to... ) wanted GC, the problem was that they had a huge cache which took a long time for the GC to scan. They could shrink the cache and it would remain performant in the face of GC, but they took latency hits due to increased cache misses. After a bunch of testing and tweaking they found a goldilocks zone where performance was okay.

Rust was introduced because it was already something other teams were interested in, and when they tried a quick prototype, they avoided the issue entirely, and saw better performance even in the prototype than their finely tuned Go code, so they switched to it.

Re: Go does not need a Java-style GC

#83
post #56

Earlier quoted context omitted.

FWIW. This would probably present a challenge in most (all?) languages. For example in libc++ due to SSO an std::string has a minimum size of 24 bytes. For a billion strings less than 15 chars (+ the null byte) that gets you to 24GB, and that’s optimistically assuming each string is allocated in place. I doubt heap allocated char* would do much better either. Just having a billion 8 byte pointers eats a lot of memory…

It's a lot easier to build custom allocators in C++ though. For one, Java has a maximum mmap-size of 2 Gb, and as a cherry on top of that turd, you have no control over their lifecycle. The language is very clearly not designed for this type of work, and if you try to make it do it anyway, it fights you every step of the way.

It has nothing to do with the language but with the API / VM capabilities.

Both those restrictions are fixed, granted that this is not yet in the offical API, it's an incubation module (the equivalent of from __future__ of Python).

https://docs.oracle.com/en/java/javase/17/docs/api/jdk.incub...

Re: Go does not need a Java-style GC

#84
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.

Even if you need an expert, it’s safer and cheaper than rewriting the critical path several times hoping for better behavior.

Re: Go does not need a Java-style GC

#85

Earlier quoted context omitted.

Even if it doesn't need specifically a compacting QC having a swappable more tunable one might still be a big deal for people who need something other than the current GC. Like a simple example is the Discord article about how their use case could not work with Go because it always ran the GC every two minutes. If they could optionally disable that feature they theoretically could have kept using Go instead of rewrit…

That wasn't my read. The Discord team that wrote the article I believe you're referencing ( https://discord.com/blog/why-discord-is-switching-from-go-to... ) wanted GC, the problem was that they had a huge cache which took a long time for the GC to scan. They could shrink the cache and it would remain performant in the face of GC, but they took latency hits due to increased cache misses. After a bunch of testing and…

To me it sounded like if they could have turned off the auto scan on a time limit it would have been fine because once it was fully up and running they didn't really need GC because the memory footprint was stable. But because they had no way of turning that off without compiling their own version of the runtime it wasn't tenable.

Re: Go does not need a Java-style GC

#86

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.Right != -1 {
                  return uint32(1) + itemCheck(tree.Right, pool) + itemCheck(tree.Left, pool)
          }
          return 1
  }

  func bottomUpTree(depth uint32, pool *[]Tree) int {
          var tree Tree
          if depth > uint32(0) {
                  tree.Left = bottomUpTree(depth-1, pool)
                  tree.Right = bottomUpTree(depth-1, pool)
          } else {
                  tree.Left = -1
                  tree.Right = -1
          }
          id := len(*pool)
          *pool = append(*pool, tree)
          return id
  }

  func inner(depth, iterations uint32) string {
          var (
                  pool []Tree
                  chk  = uint32(0)
          )
          for i := uint32(0); i 
If it matters, your Go program can be made as fast as a C program.

Easily.

Re: Go does not need a Java-style GC

#87
post #69
post #55

Earlier quoted context omitted.

ZGC and Shenandoah can be slower than G1, those are not silver bullets. The fact that there is 4-5 GCs explains the situation, there is not a single GC that is better than the others. It really depends of the workload.

Indeed. It is strange that no official JDK document puts pros/cons of GCs packaged with standard JDKs in some kinda easy-to-read table/matrix.

Well, unless latency is explicitly a problem with the default (G1) GC, it probably should not be changed to begin with. It is a beast of a GC with a very good balance between throughput and latency. Also, if the latter is problematic, the first thing should be to fiddle with the singular G1 knob (one should set, unless they really know what they are doing), target pause time — throughput and latency are fundamentally opposing goals.

G1 by default has low enough pauses as well, but it does increase with the speed of garbage creation. But it handles even ridiculously high throughputs with graceful degradation of pause times.

Here is a really great blog on various aspects of modern GCs (and don’t forget that we are at Java 17, with small but significant GC updates in each version): https://jet-start.sh/blog/2020/06/23/jdk-gc-benchmarks-remat...

Re: Go does not need a Java-style GC

#88
post #31

Earlier quoted context omitted.

Even if it doesn't need specifically a compacting QC having a swappable more tunable one might still be a big deal for people who need something other than the current GC. Like a simple example is the Discord article about how their use case could not work with Go because it always ran the GC every two minutes. If they could optionally disable that feature they theoretically could have kept using Go instead of rewrit…

You can disable the GC in go. https://pkg.go.dev/runtime/debug#SetGCPercent

Also in java, with the Epsilon “GC”. But it is not really meant for programs that have to run for weeks.

Re: Go does not need a Java-style GC

#89
post #27

Earlier quoted context omitted.

While I agree that the java gRPC lib is better maintained, I don’t agree with your second point. Java’s GCs are the state of the art, that can manage heap sizes up to 16 tera bytes. Other GC implementations would simply die there.

That’s neat, but a lot of applications will never need 16TB.

They are a beast in throughput as well (as well as alternatively, really really good at low-latency with the new GCs made specifically for that): https://news.ycombinator.com/item?id=29323468
Post reply on HN