4 ms·
> And lacks most of the advanced optimizations you'd expect from a modern GC. It can't move objects around, it doesn't have generations, it doesn't have good di
by lossolo 2y ago
> And lacks most of the advanced optimizations you'd expect from a modern GC. It can't move objects around, it doesn't have generations, it doesn't have good diagnostics (it can't even show you what are the GC roots for its hierarchy in a crash dump), and so on.
Due to the choices and tradeoffs they made, Go doesn't require most of these 'advanced optimizations.' The way allocation works in Go, along with its use of value types etc, eliminates the need to move objects around or use generations. You can read more about this here [2][3].
> it doesn't have good diagnostics
I'm not sure that's true for me personally; I find that it has good enough diagnostics to quickly locate all GC problems using the profiler and GC tracer. You can read more about this here [1].
1. https://tip.golang.org/doc/gc-guide#Identiying_costs https://tip.golang.org/doc/gc-guide#Identiying_costs
2. https://go.dev/blog/ismmkeynote https://go.dev/blog/ismmkeynote
3. https://itnext.io/go-does-not-need-a-java-style-gc-ac99b8d26c60 https://itnext.io/go-does-not-need-a-java-style-gc-ac99b8d26...
- tsimionescu 2y agoThose articles claim that these problems don't exist in Go, but they don't really explain why, for many of them. The one part that is clear indeed is that the pervasive use of value types in Go reduces the amount of garbage that gets generated compared to Java or C#, and, of course, less garbage means less time spent on GC. The claims about memory fragmentation are less clear though: the first article just says that it's not a problem; and the second one does have a segment dedicated to it, but that segment gets fragmentation completely mixed up with memory locality, an entirely unrelated concept. It later claims that certain allocators are known to not suffer from fragmentation issues, but given the previous confusion, I'm not sure how seriously to take this. It also doesn't say if Go actually uses those allocators or not. As for the diagnostics, I gave a specific example of a very commonly needed diagnostic, identifying GC roots to understand why a memory leak is occurring, that Go simply doesn't provide (someone else suggested a third party package that might help). I am well aware of the basics provided in the article you linked, and they don't even discuss this. For whatever bizarre reason, the Go memory tools don't provide this info (that the GC obviously needs to determine in its operation) - probably another victim in their quest of making it easier to implement the runtime.
- lossolo 2y ago> The claims about memory fragmentation are less clear though As to memory fragmentation, memory allocations are grouped by size, so when objects of the same size are allocated and freed, the memory can be reused efficiently without causing fragmentation. So Go's memory allocator organizes memory into size classes, which are predefined blocks of different sizes. When an object is allocated, it fits into the smallest available size class that can accommodate it. This reduces internal fragmentation (unused space within allocated blocks). > As for the diagnostics, I gave a specific example of a very commonly needed diagnostic, identifying GC roots to understand why a memory leak is occurring, that Go simply doesn't provide (someone else suggested a third party package that might help). I am well aware of the basics provided in the article you linked, and they don't even discuss this. For whatever bizarre reason, the Go memory tools don't provide this info (that the GC obviously needs to determine in its operation) - probably another victim in their quest of making it easier to implement the runtime. Can't you just use pprof to find memory leaks?[1] You can even get a diagram showing where allocations occur and see which lines of code allocate the most memory. In all the cases where I was investigating memory leaks, pprof was sufficient. Do you have any common examples where this wouldn't work? 1. https://www.codereliant.io/memory-leaks-with-pprof/ https://www.codereliant.io/memory-leaks-with-pprof/
- tsimionescu 2y agoPprof shows where allocations happen, which doesn't tell you why an object is still present in memory, who is holding onto it. I've had to trawl through lots of third-party code to figure out who was holding onto some strings, for example. "Who originally allocated X" and "who is holding onto the last reference to X" are not directly linked concepts. Especially in a language that is happy to leak an entire array if a slice is holding onto three elements of it.
- lossolo 2y agoI see, thanks. Well, I've had similar problems, though not many. Maybe we just design things more carefully, but whenever we did encounter issues, knowing where the allocation happened was 90% of the investigation. The rest was just using the IDE features to see all possible references to that variable and go through the graph. At least that's my experience.