嘿嘿。 protobuf.net 的长期爱好者。
尽管是快速提问。我有一个高度多线程的 C# 应用程序,它每秒反序列化大约 100 个对象,总计大约 50MB/秒。我看到内存使用量非常大,远远超过我正在反序列化的内存使用量。我已经通过“Red Gate ANTS Memory Profiler”运行应用程序,它向我展示了由于 protobuf(超过 50% 的应用程序使用)而产生的大量第 2 代内存对象。大多数对象都是 int 值并链接到:
- TypeModel.TryDeserializeList()
- ProtoBuf.Meta.BasicList
任何减少此第 2 代内存使用的帮助将不胜感激。
马克
最佳答案
在我看来,这里的根 T 是数组本身,即
int[] values = Serializer.Deserialize<int[]>(source);
如果是这种情况,那么当前它会针对该场景使用略微次优的路径(原因是:使用相同代码路径,即使在具有弱元编程/反射模型的平台,例如 iOS)。我会尝试花几个小时整理一下,但在回答你的问题时 - 你应该能够通过添加父对象来避免这里的问题:
[ProtoContract]
public class MyDataWrapper { // need a new name...
[ProtoMember(1)]
public int[] Values { get;set; }
}
然后:
int[] values = Serializer.Deserialize<MyDataWrapper>(source).Values;
这实际上与已经通过 Serialize<int[]>
序列化的数据完全兼容, 只要使用的字段编号是 1
.这种方法的另一个好处是,如果需要,您可以使用“打包”子格式(仅适用于列表/原语数组,例如 int);尽管在这种情况下可能仍然不是一个好主意,因为它的长度很大(序列化时可能需要缓冲)。
附加上下文;这里的“v1”基本上使用 MakeGenericType 即时切换到类似上面的内容;然而,由于这种方法在“v2”所针对的许多其他平台中不可用,因此它在这里使用了一种不太优雅的方法。但现在它在那里非常稳定,我可以在完整的 .NET 2.0 或更高版本上运行时重新添加优化版本。
关于c# - Protobuf.net 内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8450171/