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.
Go does not need a Java-style GC
41–50 of 226 posts
Re: Go does not need a Java-style GC
#42Earlier quoted context omitted.
The Java gRPC SDK is heavily optimized by Google, much more than the Go one. Until recently Java pauses were a real issue, I worked with a lot of Java based solutions ( elastic search, hadoop etc ... ) and was never impressed by the GC.
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.
Re: Go does not need a Java-style GC
#43I'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…
Re: Go does not need a Java-style GC
#44Earlier quoted context omitted.
As I said the Java SDK is heavily optimized to do the least minimum of allocations. I mean if you don't allocate much the GC is not really an issue.
OK but again, that is a statement totally contrary to the article. The article is claiming two things: that it is easier in Go to avoid the heap while Java is utterly dependent on allocating everything on the heap - which is not consistent with the experience of actual Java and Go programmers - and that Java has a "preference for high throughput and high latency" which it doesn't.
I'd be very surprised if the same wasn't possible in Java.
I don't know if this is how gRPC is written but it could explain an apparent contradiction.
Re: Go does not need a Java-style GC
#45Earlier quoted context omitted.
Max pause times of 0.5ms is what got me really interested. It feels like a huge trade-off of GCs is almost completely gone. https://malloc.se/blog/zgc-jdk16
There's still a memory tradeoff, some due to GC, some due to Java (lots of runtime reflection...). Guessing 2-4x.
In terms of just data, that should clock in at about 10 Gb; in practice it was closer to 24 Gb. I tried going with just byte[]-instances instead, which didn't help a lot. Using long byte[]-instances and indexing those doesn't help as much as you'd think because they get sliced up into small objects behind the scenes.
I ended up memory mapping blocks of memory and basically implementing my own append-only allocator.
Re: Go does not need a Java-style GC
#46Wait, what?
What's wrong with:
char theHeap[0x1000000];
atomic_ulong bumpPtr;
void* bump_malloc(int size){
uint32_t returnCandidate = bumpPtr.fetch_add(size, std::memory_order_relaxed);
if(returnCandidate + size >= HEAP_SIZE){
// Garbage collect. Super complicated, lets ignore it lol.
// Once garbage collect is done, try to malloc again. If fail then panic().
}
return &theHeap[returnCandidate];
}
------You don't even need acq_release consistency here, as far as I can tell. Even purely relaxed memory ordering seems to work, which means you definitely don't need locks or even memory barriers.
The exception is maybe the garbage-collect routine. Locking for garbage collect is probably reasonable (other programmers accept that garbage-collection is heavy and may incur a large running + synchronization costs), but keeping locks outside of the "hot path" is the goal.
------
This is what I do with my GPU test programs, where locking is a very, very bad idea (but possible to do). Even atomics are kinda-bad in the GPU world but relaxed-atomics are quite fast.
-------
> In Java, this requires 15 000 separate allocations, each producing a separate reference that must be managed.
Wait, what?
points [] array = new points[15000];
This is a singular alloc in Java. 15000 _constructors_ will be called IIRC (My Java is rusty though, someone double-check me on that), but that's not the same as 15000 allocs being called, not by a long shot.------
Frankly, it seems like this poster is reasonably good at understanding Go performance, but doesn't seem to know much about Java performance or implementations.
Re: Go does not need a Java-style GC
#47There are very few falsifiable statements in this article but the extant ones are all demonstrably false, starting with this whopper: "This typically causes Java programs to have complete freezes of several hundred milliseconds where objects get moved around" Yeah, i mean, definitely not. The only language I regularly work with that has this property is, surprise, Go. The proof is in the tasting, as they say. Go look…
I was disappointed with the first Go gRPC implementation, it allocated like crazy and was really slow because of it. It's been rewritten since then but I don't know how much better it is now. To get good performance out of Go it is important to think about memory allocations (unfortunately), just as it is in C and C++. Although allocating like crazy in C/C++ will probably mostly result in a general loss of performance, not affect tail latencies in network protocols much.
Re: Go does not need a Java-style GC
#48Given that Java is not far behind C and C++ for many kinds of workload and in quite some scenarios can outperform C code, I'm not sure that I buy this line of reasoning.
> Doing these updates requires freezing all threads.
Eh, what? There are multi-threaded GCs, what is this article even talking about?
> However, this does not put C# and Java on equal footing with languages like Go and C/C++ in terms of memory management flexibility
In which world are Go and C in the same worlds when it comes to memory management flexibility? That's like comparing a language that uses a Garbage Collector to one that requires manual memory management. Because - it is.
> Modern Languages Don’t Need Compacting GCs
> If need be, the Pacer slows down allocation while speeding up marking.
So, you just traded in one drawback for another?
Heck, I get it. The JVM is not a thin graceful fawn. It's a complicated beast that requires years of experience to tame it - and even then it will come back from time to time an bite you. There are many good points to critique the JVM - but I don't get the feeling that the author of this article has spent much time with modern JVMs because he's not pointing out any of them.