我希望在运行时回收protobuf的消息对象来减少GC消耗,但不确定是否安全。以下是测试样例代码:
test.proto
message Hello{
uint32 id = 1;
}
test.pb.go
type Hello struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ID uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (x *Hello) Reset() {
*x = Hello{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_login_api_login_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
// other codes
main.go
func main() {
// Disable GC to test re-acquire the same data
gc := debug.SetGCPercent(-1)
// As a protobuf object pool
cache := sync.Pool{New: func() interface{} { return &test.Hello{} }}
// Take out an object and use it
m1 := cache.Get().(*test.Hello)
m1.ID = 999
fmt.Println(&m1.ID) // print 999
// Empty the data and put it back into the object pool
m1.Reset()
cache.Put(m1)
// Take out an object again and use it
m2 := cache.Get().(*test.Hello)
fmt.Println(&m2.ID) // print 0
debug.SetGCPercent(gc)
}
* x = Hello {}
,当调用Reset()
函数时,似乎在函数内部创建了一个临时对象并分配给变量x
。这不会改变数据的原始指针吗?谢谢。 - null*x = Hello{}
中x
前面的星号表示指针被解引用了。这行代码基本上与将每个字段单独设置为其默认值相同。指针保持不变,只是它所指向的数据被更改了。 - Dylan Reimerink