-1
func main() {
 var cs CustomStruct
 r := []byte{.......}
 err:=proto.Unmarshal(r, &cs)
 if err!=nil {
    panic(err)
  } 
}

当我跑步时go build -gcflags="-m" ./... ,我得到

移动到堆:CustomStruct

但稍作改动,它就不会移动到堆中:

func main() {
 var cs *CustomStruct
 r := []byte{.......}
 err:=proto.Unmarshal(r, cs)
 if err!=nil {
    panic(err)
  } 
}

现在,当我运行 escape-analysis 命令时,它并没有说它CustomStruct被移到了堆中。这里到底发生了什么?

4

2 回答 2

1

由于 的地址cs被发送到一个函数,并且该函数可能会在函数返回后生成可能持有对的引用的 goroutine cs,因此将其移动到堆中。

在第二种情况下,cs是一个指针。不需要将指针本身移动到堆中,因为函数Unmarshal可以引用的是 指向的对象cs,而不是cs自身。您没有显示如何cs初始化,因此这段代码将失败,但是如果您初始化cs指向在该函数中声明的变量,则该对象可能最终会出现在堆中。

于 2021-08-26T03:33:27.800 回答
0

proto.Unmarshal

func Unmarshal(buf []byte, pb Message)
type Message interface {
    Reset()
    String() string
    ProtoMessage()
}

interface{} 可以是每一种类型,编译时很难确定其参数的具体类型,也会出现逃逸。

但如果 interface{} 是一个指针,它只是一个指针

于 2021-08-26T03:35:02.237 回答