mud*_*dxr 7 .net c# serialization protocol-buffers protobuf-net
我正在使用协议缓冲区序列化序列化大型数据集.当我的数据集包含400000个大小约为1 GB的自定义对象时,序列化将在3~4秒内返回.但是当我的数据集包含大约1.2 GB的450000个组合大小的对象时,序列化调用永远不会返回并且CPU会不断消耗.
我正在使用Protocol Buffers的.NET端口.
看一下新的评论,这似乎是(作为OP注释)MemoryStream容量有限.protobuf规范中的一个小麻烦是,由于子消息长度是可变的并且必须在子消息前面加上,因此通常需要缓冲部分直到长度已知.这对于大多数合理的图表来说都很好,但是如果有一个特别大的图形(除了"根对象有数百万个直接子节点"的场景,它没有受到影响)它最终会在内存中做很多事情.
如果你没有绑定到特定的布局(可能是因为.proto与现有客户端互操作),那么一个简单的修复如下:在子(子对象)属性(包括子对象的列表/数组),告诉它使用"组"序列化.这不是默认布局,但它表示"不使用长度前缀,而是使用开始/结束对令牌".这样做的缺点是,如果您的反序列化代码不知道某个特定对象,则跳过该字段需要更长的时间,因为它不能只是说"向前寻找231413个字节" - 而是必须使用令牌才能知道当对象完成时.在大多数情况下,这根本不是问题,因为您的反序列化代码完全期望数据.
去做这个:
[ProtoMember(1, DataFormat = DataFormat.Group)]
public SomeType SomeChild { get; set; }
....
[ProtoMember(4, DataFormat = DataFormat.Group)]
public List<SomeOtherType> SomeChildren { get { return someChildren; } }
protobuf-net中的反序列化是非常宽容的(默认情况下有一个可选的严格模式),它会愉快地反序列化组来代替length-prefix,而length-prefix代替组(意思是:你已经存储的任何数据)某个地方应该工作正常).
1.2G 内存非常接近 32 位 .Net 进程的托管内存限制。我的猜测是连载会触发一切OutOfMemoryException,一切都会崩溃。
您应该尝试使用几个较小的序列化而不是一个巨大的序列化,或者迁移到 64 位进程。
干杯,弗洛里安