进行逃逸分析,将变量声明为指针。

huangapple go评论78阅读模式
英文:

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

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

When I run go build -gcflags="-m" ./... , I get

> moved to heap: CustomStruct

But with a small change, it does not get moved to the heap:

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

Now when I run the escape-analysis command, it doesn't say that CustomStruct gets moved to the heap. What exactly is going on, here?

答案1

得分: 1

由于cs的地址被发送到一个函数,并且该函数可能会生成持有对cs的引用的goroutine,因此它被移动到堆上。

在第二种情况下,cs是一个指针。没有必要将指针本身移动到堆上,因为Unmarshal函数所引用的是cs指向的对象,而不是cs本身。你没有展示cs是如何初始化的,所以这段代码会失败。然而,如果你将cs初始化为指向在该函数中声明的变量,那个对象很可能会最终位于堆上。

英文:

Since the address of cs is sent to a function and that function may spawn goroutines that may hold a reference to cs after the function returns, it is moved to heap.

In the second case, cs is a pointer. There is no need to move the pointer itself to the heap, because that the function Unmarshal can refer to is the object pointed to by cs, not cs itself. You didn't show how cs is initialized, so this piece of code will fail, however if you initialize cs to point to a variable declared in that function, that object will likely end up in the heap.

答案2

得分: 0

proto.Unmarshal

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

interface{}可以表示任意类型,在编译期间很难确定其参数的具体类型,并且可能会发生逃逸。

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

英文:

proto.Unmarshal

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

interface{} can be every type, It is difficult to determine the specific types of its parameters during compilation, and escape will also occur.

but if interface{} is a pointer, it just a pointer

huangapple
  • 本文由 发表于 2021年8月26日 10:59:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/68931975.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定