C# 如何最大限度地减少Protobuf.NET内存消耗

C# 如何最大限度地减少Protobuf.NET内存消耗,c#,.net,protobuf-net,C#,.net,Protobuf Net,我正在使用Protobuf.NET序列化大量的类,其中大多数是作为引用的(因为我在数据结构中有多个对相同类的引用) 通过使用ImplicitFirends.AllFields对所有序列化的类进行序列化,以确保 一切都被抛弃了 在我当前的测试用例中,我有53个文件,总大小为500MB 当我使用Protobuf.NET反序列化程序读取此数据时,我的私有字节/驻留内存将达到9GB并保持在那里(即,这不是反序列化后释放的临时内存/GC) 另一件奇怪的事情是,如果我重新写入(重新序列化)所有数据,它仍然保

我正在使用Protobuf.NET序列化大量的类,其中大多数是作为引用的(因为我在数据结构中有多个对相同类的引用)

通过使用ImplicitFirends.AllFields对所有序列化的类进行序列化,以确保 一切都被抛弃了

在我当前的测试用例中,我有53个文件,总大小为500MB

当我使用Protobuf.NET反序列化程序读取此数据时,我的私有字节/驻留内存将达到9GB并保持在那里(即,这不是反序列化后释放的临时内存/GC)

另一件奇怪的事情是,如果我重新写入(重新序列化)所有数据,它仍然保持相同的大小


这个x20在内存中爆炸有意义吗?

我将运行一些测试,但听起来它是用来避免分配的缓冲池。除了测试之外,我将在下一个版本中添加一个“转储池”方法(并禁用?)。事实上,仔细想想:我会将它们更改为
WeakReference
,这样它们可以在存在时重复使用,但仍然可以收集


您还可能会发现(作为合同上的一个选项),对子对象和列表使用“组”编码在这里会大大减少;长度前缀是默认值(也是谷歌的首选选项),但组的写入效率要高得多,因为它们可以直接写入而无需任何缓冲。如果你想举个例子,请告诉我。Protobuf net的设计使它们之间的切换不是一个突破性的改变,但其他Protobuf客户端不会那么宽容,因此,如果您使用Protobuf与其他系统进行互操作,则更为棘手。

我不确定这是否真的是缓冲池。当我转储堆时,我看到多个(即10000或更多)本应在一位数范围内的类实例。有没有办法验证AsReference“功能”是否真的有效?我有一个特定的类,它被设置为编码为引用,我确实应该有其中一个,但我似乎有超过10000个。。。这让我怀疑AsReference功能…@damageboy它肯定很容易从您的数据验证-只需调用ReferenceEquals。如果您可以展示一个场景的小示例,这会有所帮助,请注意,引用仅在单个图形操作期间有效-如果单独调用反序列化5次,则仍然是5个对象,而不是一个。这里就是这样吗?我想,可能还有其他选择(包括我多年来一直打算实现的核心.NET引用交换接口,它可能允许你做你想做的事情)。。。如果我有一个继承场景,其中C派生自B,B派生自A。。。所有这些课程都应该标记为参考吗?嗨,马克,我的情况似乎有点复杂。我标记为“AsReference”的一些类确实被序列化为引用并通过了ReferenceEquals测试,而其他更复杂的类,可能是具有继承性的类,则没有,基本上是复制的。。。在涉及子类型和继承的场景中是否支持AsReference?@damageboy应该支持,但这很复杂。我得测试一下。