func main() {
i1 := 1
A1(&i1)
}
func A1(i1 *int) *int {
return i1
}
逃逸分析的结果是:
./main.go:18:9: parameter i1 leaks to \~r1 with derefs=0:
./main.go:18:9: flow: \~r1 = i1:
./main.go:18:9: from return i1 (return) at ./main.go:19:2
./main.go:18:9: leaking param: i1 to result \~r1 level=0
“parameter i1 leaks to \~r1 with derefs=0” 的意思是参数 i1 泄漏到了内存区域 \~r1 ,且没有被引用(derefs=0)。
“leaking param: i1 to result \~r1 level=0” 的意思是参数 i1 漏出到结果返回值 \~r1 中,并且层级为 0。
首先,我尝试谷歌搜索“golang escape leaking”,最相关的结果出现在escape-analysis-shows-channel-as-leaking-param的评论中。
“你为什么会这样认为?”假设泄露是不好的,并与其词源 leak 相关。 我正在努力想出泄漏是好事的例子,例如泄漏的桶,泄漏的气罐,排放物,泄漏的电容器,漏水的船,泄漏的抽象。 对于高性能的 Go 专家来说可能显而易见,但对于我们其他人来说,将文档链接和提供有关 leaking param 是什么的简要澄清将会很有帮助。
这正是我想要问的问题,但之后就没有更多的回复了。
接着,我试图阅读打印这些结果的源代码。
在 compile/internal/escape/leaks.go中,我发现了以下注释:
// An leaks represents a set of assignment flows from a parameter
// to the heap or to any of its function's (first numEscResults)
// result parameters.
但是我不能理解这个注释,是否有官方文档来解释呢?
此外,在源代码中我还发现了一个问题:当numEscResults(7)之后的结果参数会在运行时逃逸到堆中吗?
func main() {
i1, i2, i3, i4, i5, i6, i7, i8, i9 := 1, 1, 1, 1, 1, 1, 1, 1, 1
A1(&i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9)
return
}
func A1(i1, i2, i3, i4, i5, i6, i7, i8, i9 *int) (*int, *int, *int, *int, *int, *int, *int, *int, *int) {
return i1, i2, i3, i4, i5, i6, i7, i8, i9
}
...some duplicate output
./main.go:16:13: leaking param: i2 to result ~r10 level=0
./main.go:16:17: leaking param: i3 to result ~r11 level=0
./main.go:16:21: leaking param: i4 to result ~r12 level=0
./main.go:16:25: leaking param: i5 to result ~r13 level=0
./main.go:16:29: leaking param: i6 to result ~r14 level=0
./main.go:16:33: leaking param: i7 to result ~r15 level=0
./main.go:16:37: leaking param: i8
./main.go:16:41: leaking param: i9
./main.go:8:30: i8 escapes to heap:
./main.go:8:30: flow: {heap} = &i8:
./main.go:8:30: from &i8 (address-of) at ./main.go:9:40
./main.go:8:30: from A1(&i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9) (call parameter) at ./main.go:9:4
./main.go:8:34: i9 escapes to heap:
./main.go:8:34: flow: {heap} = &i9:
./main.go:8:34: from &i9 (address-of) at ./main.go:9:45
./main.go:8:34: from A1(&i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9) (call parameter) at ./main.go:9:4
./main.go:8:30: moved to heap: i8
./main.go:8:34: moved to heap: i9