Protobuf.net内存使用情况

Mar*_*rcF 6 c# protobuf-net

Heyup.protobuf.net的长期爱好者.

但是问题很快.我有一个高度多线程的C#应用​​程序,可以反序列化大约100个对象/秒,大约50MB /秒.我看到非常大的内存使用量,远远超过我正在反序列化的内存.我通过'Red Gate ANTS Memory Profiler'运行应用程序,由于protobuf(超过50%的应用程序使用),它向我展示了大量的第2代内存对象.大多数对象都是int值,并与以下内容链接:

- TypeModel.TryDeserializeList()
- ProtoBuf.Meta.BasicList
Run Code Online (Sandbox Code Playgroud)

任何帮助减少这个第2代内存使用将是值得赞赏的.

Mar*_*ell 5

听起来我这里的根T就是数组本身,即

int[] values = Serializer.Deserialize<int[]>(source);
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,那么目前它对该场景使用稍微次优的路径(原因是:即使在具有弱元编程/反射模型的平台上使用相同的代码路径,例如iOS).我会尝试花几个小时整理一下,但在回答你的问题时 - 你应该能够通过添加一个父对象来避免这个问题:

[ProtoContract]
public class MyDataWrapper { // need a new name...
    [ProtoMember(1)]
    public int[] Values { get;set; }
}
Run Code Online (Sandbox Code Playgroud)

然后:

int[] values = Serializer.Deserialize<MyDataWrapper>(source).Values;
Run Code Online (Sandbox Code Playgroud)

这实际上与已经序列化的数据完全兼容Serialize<int[]>,只要使用的字段编号是1.这种方法的另一个好处是,如果需要,你可以使用"压缩"子格式(仅适用于诸如int的基元列表/数组); 虽然在这种情况下可能仍然不是一个好主意,因为它的长度很长(在序列化时可能需要缓冲).


附加背景; "v1"这里基本上使用MakeGenericType切换到类似上面的东西; 然而,由于这种方法在"v2"目标的许多其他平台中不可用,因此它在这里采用了不太优雅的方法.但是现在它非常稳定,我可以在完整的.NET 2.0或更高版本上运行时重新添加优化版本.