使用protobuf-net,是否可以在不分配内存的情况下反序列化消息?

时间:2012-01-16 18:08:47

标签: c# protobuf-net

我有一个C#应用程序需要每秒反序列化数千个protobuf消息。为了避免不必要的垃圾收集,我想知道是否有办法使用预先分配的内存,这样每个反序列化操作都不需要分配新的内存。

我想到的是,我会在执行之前分配一个消息对象池,然后指示protobuf代码使用此池中的下一个可用消息进行每次反序列化。

此功能是否存在,或者是否有其他方法可以优化内存使用?

谢谢!

1 个答案:

答案 0 :(得分:10)

是的,有!在内部,它已经使用微池来避免分配太多的工作缓冲区,但是如果你通过足够的对象来解决GC问题,你可以使用自己的分配方案,并创建一个自定义对象工厂;目前无法在属性上指定,但可以通过类型模型应用:

RuntimeTypeModel.Default.Add(typeof (Foo), true).SetFactory(factory);

其中factory是:

  • staticFoo方法的名称(即"CreateFoo"),返回Foo
  • 任何MethodInfo方法的static(不需要在Foo上),返回Foo

在任何一种情况下,该方法都可以使用相同的签名作为回调 - 因此它可以是无参数的,或者可以接受上下文信息。例如:

public static Foo CreateFoo() {
    return GetFromYourOwnMicroPool();
}

请注意,在此用法中,预计工厂会将对象重置为vanilla状态; protobuf-net不会尝试这样做。另请注意,目前protobuf-net并未将其微池作为可重用组件公开,但您可以轻松地重新使用该源。

此功能专门用于支持吞吐量非常高的用户,他希望删除最轻微的GC开销(基于大量测量...他们向我发送了漂亮的图表和所有内容; p)

此外:除根对象外,protobuf-net支持struct值,无需装箱;因此,如果您有一个复杂/嵌套的对象模型,则在极端情况下的另一个选项是查看struct s。