6 ms·
As far as I understand this Go will always try to keep objects on the stack because it is practically free (just as in C/C++). However, if the object escapes to
by mwuertinger 8y ago
As far as I understand this Go will always try to keep objects on the stack because it is practically free (just as in C/C++). However, if the object escapes to the heap then allocation gets expensive (just as in any other language) and it can be beneficial to reuse objects instead of allocating new ones for every iteration.
- HohPum1l 8y agoIdeally it would still stack-allocate where beneficial and only materialize the object once it escapes to the heap, at least that's what graalvm does
- presscast 8y ago>However, if the object escapes to the heap Can this be detected statically?
- mwuertinger 8y agoYes this is decided at compile time. If you build your program with `-gcflags '-m'` the compiler will print out detailed escape analysis information. Here's more information: http://www.agardner.me/golang/garbage/collection/gc/escape/analysis/2015/10/18/go-escape-analysis.html http://www.agardner.me/golang/garbage/collection/gc/escape/a...
- presscast 8y agoNice! So this could presumably be built into a linter (or similar) and be flagged in the editor ... interesting...
- masklinn 8y agoIIRC you can't really flag an object as normally escaping so it would be very noisy.
- IshKebab 8y agoYou could do it with a subtle colouring scheme.
- dis-sys 8y agovery nice idea.
- jimmy1 8y agoAs a heuristic it would be OK, however, there are some situations where the escape analysis algorithms don't detect certain scenarios so a linter may lead you to believe things are not escaping but in reality they really are, it's also implementation specific, so something that may have escaped in go 1.10 may no longer escape in 1.11 for example. It's easy enough to profile and benchmark in go, so I would always treat that as the source of truth.
- pcwalton 8y agoIt would be better to spend this effort to add generational GC with a bump allocator to Go. That way memory allocation becomes faster for everyone, not just the tiny subset of people who use fancy tools.
- weberc2 8y agoI think you've made yourself clear. You've jumped into half a dozen threads in this post with some variation of the same comment as you do with every Go GC post. Your comment is interesting, but repeating it over and over is tiresome. Have you reached out to the Go GC team? What is their response?
- deleted 8y ago[deleted]
- masklinn 8y agoThere are heuristics — and they improve from version to version — but they're necessarily conservative: heap allocating something which doesn't escape is a performance hit, stack-allocating something which does breaks software.
- javier2 8y agoThe compiler can in certain conditions prove that a value does not escape to the heap. Ergo, this value is safe to allocate on stack.
- pcwalton 8y agoAllocation is not expensive in every other language. In Java HotSpot, JavaScript V8/SpiderMonkey, etc. it is somewhere on the order of 6 instructions. That is because those language implementations use generational garbage collectors with bump allocation in the nursery. Go should switch to this strategy as well.
- _ph_ 8y agoUnneccessary allocation is expensive in all languages. Even if the allocation is instantanious, it creates more work for the GC and thus has a performance impact on the program. The Go dev team tried multiple alternative approaches as described here: https://blog.golang.org/ismmkeynote https://blog.golang.org/ismmkeynote and the generational GC didn't compare so well against the current GC.
- pcwalton 8y agoThey did not compare a generational GC with bump allocation in the nursery to their current GC. Without that, it's not a fair comparison. Furthermore, there isn't much of a relevant difference between stack allocated and nursery allocated objects, because they have to be scanned either way--either as roots or via a Cheney scan. The difference is only in sweeping, which is incredibly fast for nursery objects. What's really important about generational GC is that heap allocation becomes nearly as cheap as stack allocation. That's a game changer.
- _ph_ 8y agoThere must have been a very good reason they tested the generational GC as they did. Your comparison of heap allocation generational GC with stack allocation is not correct. Yes, allocating in the nursery is very fast, a couple of cycles only. The stack frame gets allocated once per function call. Yes, when a GC runs, you have to scan the whole heap, including the stack. But what you are completely missing is, that allocating on the heap eventually triggers a GC, which takes cpu resources to perform. After a collection of the nursery, all surviving objects are promoted to the older generations. This promotion not only takes work, but grows the older generations which are more expensive to GC. So, while heap allocation with a generational GC is very cheap, it is not free. A large allocation count causes more frequent GC runs and objects might be promoted to older generations prematurly. As a consequence, a program that allocates less will perform better. Avoiding a high amount of heap allocations is a good way to increase your programs performance, be it by doing stack allocation, or by reusing buffers for example.