Go escape analysis, with var(s) declared as pointers

210 Views Asked by At
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?

2

There are 2 best solutions below

0
On BEST ANSWER

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.

0
On

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