首页 > 解决方案 > 转义分析,将 var(s) 声明为指针

问题描述

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被移到了堆中。这里到底发生了什么?

标签: gopointersescape-analysis

解决方案


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

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


推荐阅读