golang的变量内存分配

逃逸分析

逃逸分析不是直接的优化手段,而是一个代码分析,通过动态分析对象的作用域,为其它优化手段如栈上分配、标量替换和同步消除等提供依据,发生逃逸行为的情况有两种:方法逃逸和线程逃逸。

  • 方法逃逸:当一个对象在方法中定义之后,作为参数传递到其它方法中;
  • 线程逃逸:如类变量或实例变量,可能被其它线程访问到;

内存分配

Go是通过在编译器里做逃逸分析(escape analysis)来决定一个对象放栈上还是放堆上:不逃逸的对象放栈上,可能逃逸的放堆上

开启go编译时的逃逸分析日志

开启逃逸分析日志很简单,只要在编译的时候加上-gcflags '-m',但是我们为了不让编译时自动内连函数,一般会加-l参数,最终为-gcflags '-m -l'

Example:

package main

import (
    "fmt"
)

func main() {
    s := "hello"
    fmt.Println(s)
}
go run -gcflags '-m -l' escape.go
Output:

# command-line-arguments
escape_analysis/main.go:9: s escapes to heap
escape_analysis/main.go:9: main ... argument does not escape
hello

什么时候逃逸,什么时候不逃逸

Example2:

package main

type S struct{}

func main() {
    var x S
    _ = *ref(x)
}

func ref(z S) *S {
    return &z
}
Output:

# command-line-arguments
escape_analysis/main.go:11: &z escapes to heap
escape_analysis/main.go:10: moved to heap: z

这里的z是逃逸了,原因很简单,go都是值传递,ref函数copy了x的值,传给z,返回z的指针,然后在函数外被引用,说明z这个变量在函数內声明,可能会被函数外的其他程序访问。所以z逃逸了,分配在堆上

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,372评论 11 349
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,907评论 0 38
  • “警察同志,我是来报案的,我家发生了盗窃。”他对着警局的同志道。 “大叔,你说具体点。”一个年轻的小警察慢悠悠的对...
    先生影只阅读 395评论 2 3
  • 01.Gary说:“如果有一天你结婚了,我们在周一还是情侣,你周一还可以来我家睡。” 02.Gary说:“智孝啊,...
    没有猫er阅读 503评论 1 2
  • 01均衡膳食,饮食清淡,少吃零食,少吃外卖饮食,少喝酒。 02适当运动,要每天坚持运动至少30分钟,避免久坐,保持...
    春花秋诗阅读 495评论 4 8