我想回收protobuf的message物件來減少運行時的GC消耗,但不確定是否安全。測驗示例代碼如下:
test.proto
message Hello{
uint32 id = 1;
}
測驗.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)
}
uj5u.com熱心網友回復:
您顯示的代碼是安全的。當物件的參考在放入池后被持有時,這樣的池化變得“不安全”。您冒著競爭條件或奇怪錯誤的風險。因此,它還取決于使用您的物件的代碼。
據我所知,協議緩沖區庫和 gRPC 庫不保留對 protobuf 物件的參考。這樣做會破壞很多代碼,因為這樣的庫無法知道何時可以安全地重用。
因此,只要您確保自己的代碼在將物件放入池中后不使用它們,就應該很好。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/407076.html
標籤:
上一篇:以表格形式列印資料
下一篇:Go型別定義操作“繼承”?
