Earlier quoted context omitted.
"Scalar replacement" explodes the object into its class member variables and does not construct a class object at all. That does result in the exact same `sub %esp` (that Go would do for any struct), but it is restricted to only working if every single usage of that class type is fully inlined and the class is never passed anywhere that needs it in its object form. It's worse than what Go has. Go can stack-allocate a…
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.
Go does not need a Java-style GC
111–120 of 226 posts
Re: Go does not need a Java-style GC
#112> In a multithreaded program, a bump allocator requires locks. That kills their performance advantage. Java uses per-thread pointer bump allocators[1] > While Java does it as well, it doesn’t utilize this info to put objects on the stack. Correct, but it does scalar replacement[2] which puts them in registers instead > Why can Go run its GC concurrently and not Java? Because Go does not fix any pointers or move any o…
Scalar replacements (as currently implemented in Java) does not work in real-world programs. Well-written code does not need it. Poorly written code can not trigger it, because the JIT is too dumb and isn't getting better. There is no sane test to determine whether a piece of code will be inlined in Java. In practice anything more complex than byte array is unlikely to be inlined. Even built-in ByteBuffers aren't! Me…
Re: Go does not need a Java-style GC
#113Earlier quoted context omitted.
There's still a memory tradeoff, some due to GC, some due to Java (lots of runtime reflection...). Guessing 2-4x.
This is a bit of a tangent, but you can get into situations where Java's memory-overhead becomes pretty untenable. I was in a situation of having to keep track of ~1 billion short strings of a median length of maybe 7 characters. 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[]-i…
Re: Go does not need a Java-style GC
#114> In a multithreaded program, a bump allocator requires locks. That kills their performance advantage. Wait, 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…
Re: Go does not need a Java-style GC
#115The 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.…
However, Isaac rejected it, saying it violated the conditions.
Re: Go does not need a Java-style GC
#116Earlier 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
> It feels like a huge trade-off of GCs is almost completely gone. FWIW the tradeoff of low latency GC is usually paid in throughput. That is definitely the case for Go, which can lag very much behind allocations (so if your allocation pattern is bad enough the heap will keep growing despite the live heap being stable, because the GC is unable to clear the dead heap fast enough for the new allocations).
and no the heap will not keep growing in golang. it'll force threads to help with GC if its falling behind. thereby reducing the rate of allocations and speeding up the collection.
Re: Go does not need a Java-style GC
#117Earlier quoted context omitted.
There's still a memory tradeoff, some due to GC, some due to Java (lots of runtime reflection...). Guessing 2-4x.
Also, throughput. But latency and throughput are almost universally opposite ends of the same axis — that’s why it’s great that Java allows for choosing a GC implementation.
Re: Go does not need a Java-style GC
#118Cool article, I'm not sure I agree with the headline. I used to write low-scale Java apps, and now I write memory intensive Go apps. I've often wondered what would happen if Go did have a JVM style GC. It's relatively common in Go to resort to idioms that let you avoid hitting the GC. Some things that come to mind: * all the tricks you can do with a slice that have two slice headers pointing to the same block of memo…
How have you found Go in contrast to Java. Is the simplicity worth it?
Re: Go does not need a Java-style GC
#119Did Go ever fix that problem where short term high memory usage can cause large empty heaps because of the lack of compaction? I remember a rash of articles about this phenomena a while back. This article seems to think its not an issue so I'm wondering when it was fixed.
Re: Go does not need a Java-style GC
#120I guess it is the same reasoning like Go not needing generics.
No, it is same reasoning as Java not needing dense memory layouts