Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go 内存逃逸

一文带你轻松理解Go中的内存逃逸问题

作者:7small7

这篇文章主要给大家介绍Go中的内存逃逸问题,文中通过代码示例讲解的非常详细,对我们的学习或工作有一定的参考价值,感兴趣的同学可以跟着小编一起来学习

内存逃逸是什么

内存逃逸危害

内存逃逸现象

逃逸分析原则

内存逃逸解决

具体案例

参数为interface类型会逃逸

下面通过举例,来进一步论证逃逸分析的原则,加深一下理解

我们可以使用这个命令go build -gcflags '-m -m -l' go文件名,来查看逃逸分析的结果。

func main() {
  num := 1
  fmt.Println(num)
}

原因分析:

func Println(a ...interface{}) (n int, err error),这个函数的入参是interface类型,编译阶段无法确定其具体的参数类型,所以内存分配到堆上

变量在函数外部有引用会逃逸

func main() {
  _ = test()
}
func test() *int {
  num := 10
  return &num
}

原因分析:

变量num在函数外部存在引用,函数退出时栈中的内存(栈帧)已经释放,但引用已经被返回,如果通过引用地址取值,在栈中是取不到值的,所以Go为了避免这个情况,会将内存分配到堆上。

变量占用内存较大时会逃逸

func main() {
  //不会逃逸
  s1 := make([]int, 10, 10)
  for i := 0; i < 10; i++ {
    s1[i] = i
  }
  //会逃逸
  s2 := make([]int, 10000, 10000)
  for i := 0; i < 10000; i++ {
    s2[i] = i
  }
}

原因分析:

切片容量过大时,会产生逃逸,内存分配到堆上;容量小时,不会逃逸,内存分配依赖在栈上。

变量大小不确定时会逃逸

func main() {
  num := 10
  s := make([]int, num, num) 
  for i := 0; i < num; i++ {
    s[i] = i
  }
}

原因分析:

切片的长度和容量,虽然通过声明的变量num来指定了,但在编译阶段是未知的,并不确定num的具体值,所以会逃逸,将内存分配到堆上。

到此这篇关于一文带你轻松理解Go中的内存逃逸问题的文章就介绍到这了,更多相关Go 内存逃逸内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文