我正在调查golang的逃逸分析,但在http://npat-efault.github.io/programming/2016/10/10/escape-analysis-and-interfaces.html的帖子中,我有两点困惑:
代码一:
func Ok(f os.File) []byte {
var x [128]byte
b := x[:]
n, _ := f.Read(b)
r := make([]byte, n)
copy(r, b[:n])
return r
}
func NotOk(c net.Conn) []byte {
var x [128]byte
b := x[:]
n, _ := c.Read(b)
r := make([]byte, n)
copy(r, b[:n])
return r
}go build -gcflags "-m -l" part3_escape.go
输出:
# command-line-arguments
./part3_escape.go:64:9: leaking param: f
./part3_escape.go:68:11: make([]byte, n) escapes to heap
./part3_escape.go:73:12: leaking param: c
./part3_escape.go:74:6: moved to heap: x
./part3_escape.go:77:11: make([]byte, n) escapes to heap
# command-line-arguments
runtime.main_main·f: function main is undeclared in the main package我不知道为什么x转义(moved to heap: x)
代码二:
type S struct {
s1 int
}
func (s *S) M1(i int) { s.s1 = i }
type I interface {
M1(int)
}
func g() {
var s1 S // this escapes
var s2 S // this does not
f1(&s1)
f2(&s2)
}
func f1(s I) { s.M1(42) }
func f2(s *S) { s.M1(42) }go build -gcflags "-m -l" part3_escape.go
输出:
# command-line-arguments
./part3_escape.go:63:7: s does not escape
./part3_escape.go:77:9: leaking param: s
./part3_escape.go:78:9: s does not escape
./part3_escape.go:70:6: moved to heap: s1
<autogenerated>:1: leaking param: .this
# command-line-arguments
runtime.main_main·f: function main is undeclared in the main package我不知道为什么s1会逃脱(moved to heap: s1)
如果有人能帮我解释那就太好了,thx?
发布于 2021-09-21 16:49:57
编译器无法证明通过an接口的调用不会将指针存储在某个地方。可能存在存储指针的接口的潜在实现,因此它必须假定值可以转义。
较新的Go版本可以在内联时取消虚拟化调用,并可能避免值转义。在第二个示例中删除-l标志时,您将看到这一点。
https://stackoverflow.com/questions/69259045
复制相似问题