为什么value receiver可以减少需要回收的垃圾量?

在网上看到一个文章《Golang何时该使用指针》其中提到



如果receiver使较小的struct或者array,并且其变量都是些不变量、常量,例如time.Time,value receiver更加适合,因为value receiver可以减少需要回收的垃圾量。



然后这个博文的原文《Go Code Review Comments》中指出



if a value is passed to a value method, an on-stack copy can be used instead of allocating on the heap.



看了一些资料,似懂非懂,哪位大大能稍微通俗的解释一下,这个大概是什么原理啊?

已邀请:

toukii

赞同来自:

传“值”函数的参数最好是栈中的变量。

cholerae

赞同来自:

go 的方法本质上是语法糖,调用时会把 receiver 作为第一个参数传给函数,比如下面这段示例可能能让你看得更明白


package main
import (
"fmt"
)

type rua int

func (h rua) a(x int32) {
fmt.Println(x + int32(h))
}

func main() {
var b func(rua, int32)
b = rua.a
b(rua(1), 1)
}

如果 receiver 是一个值而不是指针,在调用时就会传进去一份拷贝,而这份拷贝是分配在栈上的。栈上的值会在函数调用结束之后自动销毁,不会动用 GC,所以可以减轻压力。


话又说回来,省下来的这点开销在大多数场景下是可以忽略不计的,但是却会埋下一个陷阱:如果某个方法期望修改原 receiver 的值,但是 receiver 是一个值,这个方法就有问题了,而且挺隐蔽。


另一方面,并不是只要是指针它指向的对象就一定在堆上,go 是会做逃逸分析的,有可能会在栈上分配空间。

要回复问题请先登录注册