golang 内存分配的位置由编译决定,不像c或c++ 使用malloc/new 就能在堆上分配内存。内存逃逸是指:当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。
二、golang内存分配基本原则- 当函数外部对指针没有引用时,优先分配在栈上。
- 当函数外部对指针存在引用时,优先分配在堆上。
- 当函数内分配一个较大对象时,优先分配在堆上。
在go build 时加上-gcflags "-m",就会对所有函数中的所有对象进行内存逃逸分析,分析结果直接显示在终端上。
四、为什么进行内存逃逸分析1.分配在堆上:分配与释放操作都存在较大开销,可能出现内存碎片,且过多的内存分配在堆上会加重GC负担。
2.分配在栈上:cpu只需要简单的“PUSH”和“RELEASE”指令即可完成内存的分配与释放。
五、go几种内存逃逸场景1.指针逃逸:对象i被分配到堆上。
package main
func test() *int {
i := 0
return &i
}
func main() {
test()
}
2.大对象分配: s被分配到栈上
package main
func stack() {
s := make([]int, 100000, 100000)
s[0] = 1
}
func main() {
stack()
}
3.动态类型逃逸
package main
func dynamic() interface{} {
i := 0
return i
}
func main() {
dynamic()
}
4.闭包逃逸:a、b 都逃到堆上
package main
import "fmt"
func fibonacci() func() int {
a, b := 0, 1
return func() int {
a, b = b+a, a+b
return a
}
}
func main() {
f := fibonacci()
fmt.Println(f())
fmt.Println(f())
}
参考文献