40

golang 逃逸分析_v1.0.0

 3 years ago
source link: https://studygolang.com/articles/29282
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

逃逸分析是golang编译器分析一个对象到底应该放到堆内存上,还是栈内存上

为何要做逃逸分析

因为对一个程序来说,使用栈内存还是堆内存他们的效率差别很大。

栈内存:

  1. 操作系统管理内存的分配和释放,不用golang的垃圾回收操心
  2. 内存的存储结构类似于数据结构中的栈,读写位置都在栈顶。
  3. 栈内存可有效放入cpu的缓存,这样读写效率就比实际内存中少1-2个数量级的时间。
  4. 缺点就是不会太大
  5. 一般局部变量,函数参数都会放在栈内存中(罗嗦一句:为什么这里使用一般呢,在C语言中,我可以告诉你是一定,但是golang里面,如果你返回了局部变量的地址,这个时候局部变量就会放在堆了,因为这个局部变量逃出了函数的作用域)。

堆内存:

  1. 需要程序自己进行管理,可以是手动申请释放,如C/C++;也可以是语言提供的垃圾回收机制释放的
  2. 堆内存的存储结构和数据结构中的堆没有半毛钱关系,它是用链表结构实现的
  3. 堆内存申请还要去内存中寻找,还会产生内存碎片
  4. 堆内存的优点就是了一申请大于0,大小随意的内存-----64位系统:只要你的系统有这么多;32位系统:最大2^32 一共4GB的内存
  5. 未知大小的变量,未知作用域的变量等。

根据堆和栈各自的优缺点后,逃逸分析存在的目的如下:

  1. 区分对象使用堆栈内存,栈内存的对象不管了,减轻垃圾回收(gc)的压力
  2. 减少内存碎片的产生。
  3. 减轻分配堆内存的开销,提高程序的运行速度。

如何确定是否逃逸

在Go中通过逃逸分析日志来确定变量是否逃逸,开启逃逸分析日志:

go run -gcflags '-m -l' stack.go # stack.go 来自于上一篇 栈结构golang的实现

# command-line-arguments
./stack.go:17:3: &Stack literal escapes to heap
./stack.go:15:18: make([]int, size) escapes to heap
./stack.go:40:7: (*Stack).IsFull s does not escape
./stack.go:21:7: (*Stack).Push s does not escape
./stack.go:47:7: (*Stack).IsEmpty s does not escape
./stack.go:30:7: (*Stack).Pop s does not escape
./stack.go:56:13: main ... argument does not escape
./stack.go:56:13: .autotmp_1 escapes to heap
./stack.go:56:13: .autotmp_2 escapes to heap
./stack.go:62:13: main ... argument does not escape
./stack.go:62:13: .autotmp_3 escapes to heap
./stack.go:62:13: .autotmp_4 escapes to heap
./stack.go:63:13: main ... argument does not escape
./stack.go:63:13: .autotmp_5 escapes to heap
./stack.go:63:13: .autotmp_6 escapes to heap
./stack.go:64:13: main ... argument does not escape
./stack.go:64:13: .autotmp_7 escapes to heap
./stack.go:64:13: .autotmp_8 escapes to heap
false 0
true 3
true 2
true 1

其中 escapes to heap 表示分配到了堆内存上。

其中 does not escape 表示分配到了栈内存上。

欢迎关注我们的微信公众号,每天学习Go知识

FveQFjN.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK