-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于 Go 逃逸分析 #222
Comments
go build 工具中的 flag -gcflags '-m' 可以用来分析内存逃逸的情况汇总,最多可以提供 4 个 "-m", m 越多则表示分析的程度越详细,一般情况下我们可以采用两个 m 分析。
escapes to heap 则表明了变量逃逸到了堆(heap)上。其中 -l 表示不启用 inline 模式调用,否则会使得分析更加复杂,也可以在函数上方添加注释 //go:noinline禁止函数 inline调用。 关于 fmt.Println 导致变量逃逸的分析 |
Go逃逸分析最基本的原则是:如果一个函数返回对一个变量的引用,那么它就会发生逃逸。 简单来说,编译器会分析代码的特征和代码生命周期,Go中的变量只有在编译器可以证明在函数返回后不会再被引用的,才分配到栈上,其他情况下都是分配到堆上。
|
堆上动态分配内存比栈上静态分配内存,开销大很多。 变量分配在栈上需要能在编译期确定它的作用域,否则会分配到堆上。 不要盲目使用变量的指针作为函数参数,虽然它会减少复制操作。但其实当参数为变量自身的时候,复制是在栈上完成的操作,开销远比变量逃逸后动态地在堆上分配内存少的多。 |
逃逸分析跟踪代码区域的变量范围,检查变量的生命周期,当检查不通过时,会分配至堆,称为逃逸。 |
The rules may continue to seem arbitrary at first, but after some trial and error with these tools, patterns do begin to emerge. For those short on time, here’s a list of some patterns we’ve found which typically cause variables to escape to the heap:
|
来自上面的文章
难道用指针会比传值代价大吗?
输出:
line13 在之前的认知里,是会逃逸的啊,现在想来,原来逃逸是要看返回值的位置。 我们再来看一下,这三个方法的汇编代码: New
Newp
Newnp
而 但是我改如何对比此时,用指针与非指针参数的大小呢? |
题主, 请问a为什么会逃逸到堆搞清楚了吗? a不是应该在栈上分配, 然后值拷贝给fmt.Println么? 想不通为什么会逃逸呢? |
经过调查, 我现在认为 |
fmt.Println(&a)并不会触发逃逸 |
fmt.Println 为什么会导致Go 变量逃逸?
go tool compile -S -m run.go
查看。变量 a 逃逸到堆。
如果不使用 fmt.Println 则不会如此,这是为什么呢?
The text was updated successfully, but these errors were encountered: