Google协议缓冲区序列化挂起写入1GB +的数据。

| 我正在使用协议缓冲区序列化序列化大型数据集。当我的数据集包含400000个自定义对象,这些对象的总大小约为1 GB时,序列化将在3-4秒内返回。但是,当我的数据集包含组合大小为1.2 GB的450000个对象时,序列化调用将永远不会返回,并且CPU会不断消耗。 我正在使用协议缓冲区的.NET端口。     
已邀请:
        查看新的注释,这似乎是(如操作说明所述)“ 0”的能力受到限制。 Protobuf规范中的一个小麻烦之处在于,由于子消息的长度是可变的,并且必须在子消息之前加上前缀,因此通常有必要缓冲部分直到知道长度。对于大多数合理的图来说,这很好,但是,如果有一个非常大的图(“根对象具有数百万个直接子代”的情况除外,这种情况不会受到影响),它最终可能会做很多事情,记忆。 如果您不受特定布局的约束(可能是由于与现有客户端的.proto互操作),则简单的解决方法如下:在子(子对象)属性上(包括子对象的列表/数组) ,告诉它使用\“ group \”序列化。这不是默认布局,但是显示为“而不是使用长度前缀,而是使用标记的开始/结束对”。这样做的缺点是,如果反序列化代码不知道某个特定对象,则跳过该字段会花费更长的时间,因为它不能只是说“寻找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中的反序列化是非常宽容的(默认情况下有一个可选的严格模式),它将高兴地反序列化组以代替长度前缀,并以反序列化序列代替组(这意味着:您已经存储的任何数据)某个地方应该可以正常工作)。     
        1.2G内存危险地接近32位.Net进程的托管内存限制。我的猜测是序列化会触发
OutOfMemoryException
,而所有地狱都会崩溃。 您应该尝试使用一些较小的序列化而不是巨大的序列化,或者转移到64位进程。 干杯, 弗洛里安     

要回复问题请先登录注册