Go 语言机制之逃逸分析( 三 )


清单 14
./main.go:22: createUserV1 &u does not escape这是说在函数 createUserV1 调用 println 不会造成 user 值逃逸到堆 。这是必须检查的,因为它将会跟函数 println 共享(u) 。
接下来看报告中的这几行 。
清单 15

Go 语言机制之逃逸分析

文章插图
 
这几行是说,类型为 user,并在第 31 行被赋值的 u 的值,因为第 34 行的 return 逃逸 。最后一行是说,跟之前一样,在 33 行调用 println 不会造成 user 值逃逸 。
阅读这些报告可能让人感到困惑,(编译器)会根据所讨论的变量的类型是基于值类型还是指针类型而略有变化 。
将 u 改为指针类型的 *user,而不是之前的命名类型 user 。
清单 16
Go 语言机制之逃逸分析

文章插图
 
再次生成报告 。
清单 17
Go 语言机制之逃逸分析

文章插图
 
现在报告说在 28 行赋值的指针类型 *user,u 引用的 user 值,因为 34 行的 return 逃逸 。
结论值在构建时并不能决定它将存在于哪里 。只有当一个值被共享,编译器才能决定如何处理这个值 。当你在调用时,共享了栈上的一个值时,它就会逃逸 。在下一篇中你将探索一个值逃逸的其他原因 。
【Go 语言机制之逃逸分析】这些文章试图引导你选择给定类型的值或指针的指导原则 。每种方式都有(对应的)好处和(额外的)开销 。保持在栈上的值,减少了 GC 的压力 。但是需要存储,跟踪和维护不同的副本 。将值放在堆上的指针,会增加 GC 的压力 。然而,也有它的好处,只有一个值需要存储,跟踪和维护 。(其实,)最关键的是如何保持正确地、一致地以及均衡(开销)地使用 。


推荐阅读