进行逃逸分析,将 var(s) 声明为指针
Go escape analysis, with var(s) declared as pointers
func main() {
var cs CustomStruct
r := []byte{.......}
err:=proto.Unmarshal(r, &cs)
if err!=nil {
panic(err)
}
}
当我运行go build -gcflags="-m" ./...
时,我得到
moved to heap: CustomStruct
但是稍作改动,它就不会移动到堆中:
func main() {
var cs *CustomStruct
r := []byte{.......}
err:=proto.Unmarshal(r, cs)
if err!=nil {
panic(err)
}
}
现在当我 运行 逃逸分析命令时,它并没有说 CustomStruct
被移动到堆中。这到底是怎么回事?
由于 cs
的地址被发送到一个函数,并且该函数可能会在函数 returns 之后生成可能持有对 cs
的引用的 goroutines,因此它被移动到堆.
在第二种情况下,cs
是一个指针。不需要把指针本身移到堆上,因为函数Unmarshal
可以引用的是cs
指向的对象,而不是cs
本身。您没有显示 cs
是如何初始化的,因此这段代码将失败,但是如果您将 cs
初始化为指向该函数中声明的变量,该对象可能最终会出现在堆中.
proto.Unmarshal
func Unmarshal(buf []byte, pb Message)
type Message interface {
Reset()
String() string
ProtoMessage()
}
interface{}可以是任何类型,编译时很难确定其参数的具体类型,也会出现escape。
但是如果 interface{} 是一个指针,它只是一个指针
func main() {
var cs CustomStruct
r := []byte{.......}
err:=proto.Unmarshal(r, &cs)
if err!=nil {
panic(err)
}
}
当我运行go build -gcflags="-m" ./...
时,我得到
moved to heap: CustomStruct
但是稍作改动,它就不会移动到堆中:
func main() {
var cs *CustomStruct
r := []byte{.......}
err:=proto.Unmarshal(r, cs)
if err!=nil {
panic(err)
}
}
现在当我 运行 逃逸分析命令时,它并没有说 CustomStruct
被移动到堆中。这到底是怎么回事?
由于 cs
的地址被发送到一个函数,并且该函数可能会在函数 returns 之后生成可能持有对 cs
的引用的 goroutines,因此它被移动到堆.
在第二种情况下,cs
是一个指针。不需要把指针本身移到堆上,因为函数Unmarshal
可以引用的是cs
指向的对象,而不是cs
本身。您没有显示 cs
是如何初始化的,因此这段代码将失败,但是如果您将 cs
初始化为指向该函数中声明的变量,该对象可能最终会出现在堆中.
proto.Unmarshal
func Unmarshal(buf []byte, pb Message)
type Message interface {
Reset()
String() string
ProtoMessage()
}
interface{}可以是任何类型,编译时很难确定其参数的具体类型,也会出现escape。
但是如果 interface{} 是一个指针,它只是一个指针