8 ms·
The last few days i've been struggling with how go decides heap vs stack. Coming from a c/c++/java background where it's super clear, malloc or new goes on the
by jfoutz 8y ago
The last few days i've been struggling with how go decides heap vs stack. Coming from a c/c++/java background where it's super clear, malloc or new goes on the heap everything else goes on the stack, i've found go a little frustrating. i still don't have a good sense of when the escape analysis will fail and things get pushed to the heap.
This article isn't about any of that. This is much lower level, and will give you insight about other languages approaches to growing addressable space. i can't say i'm thrilled with the interleaved linked lists, but it's pretty neat and works.
i don't write assembly, and i don't think real hard about how virtual address space is managed. but maybe someday it'll be important and having read this article some bells will ring. the article is cool and worth a few minutes of your time.
edit
interleaved linked lists isn't the right term. i don't think it's _wrong_ but there's much more complexity with fitting the arenas. don't listen to me, i'm a fool.
- masklinn 8y ago> Coming from a c++ background where it's super clear, new goes on the heap everything else goes on the stack AFAIK modern C++ practices eschew new/delete pretty completely, and while std::unique_ptr or std::vector will create something on the stack it's a glorified pointer, the actual data lives on the heap. Also probably doesn't help with the specific criticism but FWIW the `-m` build flag should print out heap escape. I don't know that there are editors which integrate this though. And of course there are cases where you want the escape and heap allocation, tough one possibility would be to ban escape analysis and use `new` when you want to force a heap allocation, maybe? edit: -m is pretty noisy though, lots of constructs will cause non-bypassable escapes e.g. the fmt functions will "escape" their format string and every single parameter: https://github.com/golang/go/issues/8618 https://github.com/golang/go/issues/8618
- jfoutz 8y agohappy to admit my c++ experience is very, very old. I totally understand that things have changed. But even back in the day, libraries could do stuff that hid 'new' from me. Heck, java libs will call 'new' all the time. the same goes for c/malloc I can cope with accepting a library that does god knows what. but my code, i can see stack/heap split. perhaps it's a security blanket. perhaps it's pointless. this insight is actually really helpful. in some cases i care, in some cases i turn a blind eye. maybe writing good go means i turn a blind eye all the time. unless i need to inspect the escapes - which go provides good tools for. _chin scratch_ Thanks.
- masklinn 8y ago> happy to admit my c++ experience is very, very old. I totally understand that things have changed. But even back in the day, libraries could do stuff that hid 'new' from me. Heck, java libs will call 'new' all the time. the same goes for c/malloc Yeah, Java necessarily `news` stuff, I believe it's the only way to instantiate classes (ignoring factories).
- jfoutz 8y agoEven factories. Java puts everything on the heap. There's no on the stack object. Java and go are both pass by value. Java makes it easy, because i know everything is a pointer to a thing. I (unreasonably?) freak out about go because i don't understand when an array backing a slice change. I'm just chalking it up to me being old and dumb. Seems hard to track, but tons of people do it, so the issue must be me.
- Skinney 8y agoJava does do escape analysis to allocate certain things on the stack.
- masklinn 8y ago> Even factories. I meant "ignoring factories" in the sense of "practically you don't new to get an instance out of a factory, but ultimately it does that internally so let's just ignore this as it's just nit-picking". > I (unreasonably?) freak out about go because i don't understand when an array backing a slice change. That seems like the simplest one ever: a slice is a super shitty version of an ArrayList[0], so the slice is modified on assignment (direct or via the slice), and can be replaced implicitly on reallocation. Same as the elementData member of an ArrayList. [0] because the backing buffer can trivially be shared between slices, which is not the case for ArrayList
- pjmlp 8y agoSure there is for primitive types, for objects the compiler gets to decide what lands on the stack given escape analysis, until Project Panama finally gets integrated. Additionally both IBM and Azul JVMs do have extensions for stack allocations.
- pjmlp 8y agoIt is not clear at all in Java, variables get stack allocate via escape analysis. The extent this is made depends on what JVM is being used.