Re:Go 1.18
by int_19h on Tuesday March 15, 2022 @10:16PM
(#30694519)
Go can implicitly heap-allocate even a local variable if you e.g. capture it in a closure. This is actually more implicit than you get in Java or C#.
[ Parent
| on HN ]
Java can decide to heap-allocate or not heap-allocate at runtime based on what optimizations the JIT has performed so far, and so it can change over the course of a program's run. I don't think you can get more implicit than that.
Why would Java ever heap-allocate a local, regardless of optimizations?
It can decide to heap-allocate or stack-allocate objects (when you new them) based on escape analysis, which is a JIT optimization. But that's very different from heap-allocating variables.
Then I'm not even sure what you're talking about when you say "heap-allocate even a local variable" if you don't actually mean the value of that variable. If you draw that distinction, "variables" are never allocated; spaces for values are.
Regardless, whether something is a local or not in Java still varies depending on the JIT's decisions. (Or rather, the JIT does not see local/non-local variables, only lifetimes, and whether the lifetime may extend past the JIT's current view.)
In Java, the value of the variable of a class type is not an object - it's a reference to the object. Those references are always stack-allocated. Variables of primitive types like ints are also, of course, stack allocated.
In Go, if you have a local of type int, and that local is captured by a closure, it will be allocated on the heap to extend its lifetime. Java doesn't need to do this because it requires captures to be effectively final. On the other hand, C# does the same thing as Go.