英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论