admin管理员组文章数量:1293304
In many languages, local variables are located in call stack
In JavaScript/Python, only closure variables are located in heap, because they must live beyond the function calls, they are created.
In GO, some GO types(like slice type []int
) do reference other parts of memory, like JavaScript/Python.
In GO, not all types of variables hold references, like Javascript/Python.
For example,
1) [3]int
type variable b
directly stores an array of int
's, like C, except that C allows to get access of each array element location using C syntax &b[index]
, for more control
2) int
type variable c
directly stores an int
value, like C, except that, C gives more control by providing syntax(&c
) to get location access.
In GO, my understanding is, for local variables to be on heap/stack depends on applying piler's escape analysis in example code(below),
func foo() []int {
// the array lives beyond the call to foo in which it is created
var a [5]int
return a[:] // range operator
}
that tells the piler that variable a
lives beyond its scope, so allocate in heap, but not stack.
Question:
Does the variable a
get allocated in heap?
In many languages, local variables are located in call stack
In JavaScript/Python, only closure variables are located in heap, because they must live beyond the function calls, they are created.
In GO, some GO types(like slice type []int
) do reference other parts of memory, like JavaScript/Python.
In GO, not all types of variables hold references, like Javascript/Python.
For example,
1) [3]int
type variable b
directly stores an array of int
's, like C, except that C allows to get access of each array element location using C syntax &b[index]
, for more control
2) int
type variable c
directly stores an int
value, like C, except that, C gives more control by providing syntax(&c
) to get location access.
In GO, my understanding is, for local variables to be on heap/stack depends on applying piler's escape analysis in example code(below),
func foo() []int {
// the array lives beyond the call to foo in which it is created
var a [5]int
return a[:] // range operator
}
that tells the piler that variable a
lives beyond its scope, so allocate in heap, but not stack.
Question:
Does the variable a
get allocated in heap?
- 1 Note that not all languages behave like C. In a lot of languages like javascript and lisp a closure is actually part of the stack. Only that the stack for the language is not implemented in the "stack" in the C sense but rather the stack is implemented as a linked list - which means that the stack in some languages is implemented in the heap. Javascript implementations may either implement the classic functional linked-list stack or some sort of closure discovery mechanism to capture enclosed free variables. Both behave the same. – slebetman Commented Jan 28, 2017 at 9:24
-
Here's one good series of articles about writing a Ruby interpreter in Ruby that explains the traditional implementation of closures in functional languages: hokstad./how-to-implement-closures. Note his explanation
Instead of a traditional stack, put activation frames (arguments and local variables) for function/method calls on the heap, as a linked list
-- he's implementing the stack for his interpreter in the heap – slebetman Commented Jan 28, 2017 at 9:27
1 Answer
Reset to default 14In Go, you are supposed to trust the piler to make the best decision. It will allocate memory on the stack if possible. See also the FAQ:
From a correctness standpoint, you don't need to know. Each variable in Go exists as long as there are references to it. The storage location chosen by the implementation is irrelevant to the semantics of the language.
The storage location does have an effect on writing efficient programs. When possible, the Go pilers will allocate variables that are local to a function in that function's stack frame. However, if the piler cannot prove that the variable is not referenced after the function returns, then the piler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors. Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack.
In the current pilers, if a variable has its address taken, that variable is a candidate for allocation on the heap. However, a basic escape analysis recognizes some cases when such variables will not live past the return from the function and can reside on the stack.
Without optimization (inlining), yes a
will be allocated in the heap. We can check the escape analysis by passing -gcflags='-m'
(https://play.golang/p/l3cZFK5QHO):
$ nl -ba 1.go
1 package main
2
3 func inlined() []int {
4 var a [5]int
5 return a[:]
6 }
7
8 //go:noinline
9 func no_inline() []int {
10 var b [5]int
11 return b[:]
12 }
13
14 func main() {
15 var local_array [5]int
16 var local_var int
17 println(no_inline())
18 println(inlined())
19 println(local_array[:])
20 println(&local_var)
21 }
$ go build -gcflags='-m' 1.go
# mand-line-arguments
./1.go:3: can inline inlined
./1.go:18: inlining call to inlined
./1.go:5: a escapes to heap
./1.go:4: moved to heap: a
./1.go:11: b escapes to heap
./1.go:10: moved to heap: b
./1.go:18: main a does not escape
./1.go:19: main local_array does not escape
./1.go:20: main &local_var does not escape
We see that the piler decided to allocate inlined.a
on line 5 and no_inline.b
on line 10 on the heap, because they both escape their scope.
However, after inlining, the piler noticed that the a
does not escape any more, so it determines the variable can be allocated on the stack again (line 18).
The result is that the variable a
is allocated on the main
goroutine's stack, while the variable b
is allocated on the heap. As we can see from the output, the address of b
is on 0x1043xxxx while all other are on 0x1042xxxx.
$ ./1
[5/5]0x10432020
[5/5]0x10429f58
[5/5]0x10429f44
0x10429f40
本文标签: javascriptEscape analysisStack Overflow
版权声明:本文标题:javascript - Escape analysis - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741576431a2386311.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论