我想回收protobuf的message对象来减少运行时的GC消耗,但不确定是否安全。测试示例代码如下:test.protomessage Hello{ uint32 id = 1;}测试.pb.gotype 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 codesmain.gofunc 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)}
1 回答
当年话下
TA贡献1890条经验 获得超9个赞
您显示的代码是安全的。当对象的引用在放入池后被持有时,这样的池化变得“不安全”。您冒着竞争条件或奇怪错误的风险。因此,它还取决于使用您的对象的代码。
据我所知,协议缓冲区库和 gRPC 库不保留对 protobuf 对象的引用。这样做会破坏很多代码,因为这样的库无法知道何时可以安全地重用。
因此,只要您确保自己的代码在将对象放入池中后不使用它们,就应该很好。
- 1 回答
- 0 关注
- 151 浏览
添加回答
举报
0/150
提交
取消