Go Memory escape and escape analysis
Go Memory escape
One thing to be clear about before analyzing memory escape In the program we wrote function and local variable It's stored on the stack ( Add a little pointer to the data stored on the heap It's stored on the stack Because the size of the pointer can be predicted in advance And that is Go The basic types of are also stored on the stack ), The rest of the variables are stored on the heap , The stack is controlled at the operating system level Release memory space , The heap is program controlled by default image c c++ It is necessary to indicate the location of memory space , Stack runs much faster than heap . Have GC The high-level language recycles the contents of the heap
- Go The compiler looks at the result of memory escape go build -gcflags=-m xxx.go
- The scene of memory escape
- The local variable returned by the function is a pointer variable
#
type User struct {
Name string
}
func name(s string) *User {
u := new(User) # The type of this variable is *User Pointer to the variable
u.Name = s
return u
}
func main() {
user := name("kuQi")
fmt.Println(user)
}
# command-line-arguments
./main.go:9:6: can inline name
./main.go:18:14: inlining call to name
./main.go:19:13: inlining call to fmt.Println
./main.go:9:11: leaking param: s
./main.go:10:10: new(User) escapes to heap // Cause escape
./main.go:18:14: new(User) escapes to heap // Cause escape
./main.go:19:13: []interface {}{...} does not escape
<autogenerated>:1: leaking param content: .this
2.interface Memory escape caused by dynamic type of
// fmt.Println The accepted parameter is interface Dynamic type It's hard for the compiler to determine the type of variable it receives All will 123 This variable escapes to the heap
func main() {
fmt.Println(123)
}
# command-line-arguments
./main.go:16:6: can inline main
./main.go:20:13: inlining call to fmt.Println
./main.go:20:14: 123 escapes to heap
./main.go:20:13: []interface {}{...} does not escape
<autogenerated>:1: leaking param content: .this
3. Memory escape caused by closure function
// Because a function is also a pointer type So when you take an anonymous function as the return value Memory escape will also occur The principle is similar to first reason
func BiBao() func() string {
return func() string {
return "test"
}
}
# command-line-arguments
./main.go:24:9: func literal escapes to heap:
./main.go:24:9: flow: ~r0 = &{storage for func literal}:
./main.go:24:9: from func literal (spill) at ./main.go:24:9
./main.go:24:9: from return func literal (return) at ./main.go:24:2
./main.go:24:9: func literal escapes to heap
4. Variable size cannot be determined or Not enough stack space Memory escape
ulimit -a // ulimit -a You can see that our stack space is 8192
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kbytes) unlimited
-l: locked-in-memory size (kbytes) unlimited
-u: processes 2784
-n: file descriptors 2560
// Large slice exceeds stack space Memory escape caused by
package main
func main() {
s := make([]int, 10000, 10000) // Create an oversized slice
for index, _ := range s {
s[index] = index
}
}