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


评论