golang中如何安全回收protobuf对象

我想回收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)

}


慕娘9325324
浏览 157回答 1
1回答

当年话下

您显示的代码是安全的。当对象的引用在放入池后被持有时,这样的池化变得“不安全”。您冒着竞争条件或奇怪错误的风险。因此,它还取决于使用您的对象的代码。据我所知,协议缓冲区库和 gRPC 库不保留对 protobuf 对象的引用。这样做会破坏很多代码,因为这样的库无法知道何时可以安全地重用。因此,只要您确保自己的代码在将对象放入池中后不使用它们,就应该很好。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go