如何在.NET中序列化大对象?(内存不足异常)
-
22-08-2019 - |
题
我在应用程序中使用序列化来实现“保存”功能。但是,当数据太大(15+ MB)时,我开始出现 OutOfMemory 异常。
我有很多对象,并且它们与其他小对象连接,我认为这导致内存中保存的处理能力和数据过多。
我的代码基于此,几乎相同:
http://www.codeproject.com/KB/vb/TreeViewDataAccess.aspx
编辑 :
我不使用自定义序列化,这一切都是由 [Serialization] 属性完成的。排除某些字段。
我序列化了很多对象和自定义类。包括字典、结构和一堆其他东西。
我将它序列化到一个文件中。
我使用 XmlSerializer
附:我有 4 GB 物理内存。
解决方案
感谢答案,我发现问题出在 XmlSerializer 上,我已经解决了它。二进制序列化对于我所获得的数据运行得很好。
解决方案
15MB 不应该给你带来 OOM。
如果数据是树状的(而不是完整的图),您可能会考虑像这样的序列化器 protobuf网络;以及使用谷歌非常高效(速度和内存)的二进制“协议缓冲区”格式,它受益于不必进行参考跟踪(图形所需) - 这意味着它只需要担心数据一次(如果有两次)得到缓冲)。
但是,这需要对您的类进行不同的标记(或者至少是“选择加入”),并且它无法处理完整的图表。但它就在那里,而且免费......
其他提示
我有完全相同的问题。原因是.NET序列化不会扩展。
我通过使用Simon Hewitt出色的开源库解决了问题,请参阅 优化.NET中的序列化 - 第2部分.
除了大大减少内存使用情况外,它的速度也更快。与文章类似,我得到了 20 倍的加速。
实际上,XmlSerializer 会忽略 SerializedAttribute 属性。它们仅由格式化类(BinaryFormatter、SoapFormatter)使用。
我不会使用 XmlSerializer 进行序列化,尤其不会使用 XmlSerializer 和 BinaryFormatter 的组合。
我只是尝试使用 BinaryFormatter 序列化所有内容。
您可以编写自己的序列化例程,并查看是否可以通过手动定制序列化过程来获得任何性能优势。有关更多详细信息,请参阅 有关自定义序列化的 MSDN 页面.
也许您可以向我们提供有关如何进行序列化的更多详细信息。您使用自定义序列化吗?或者您只使用内置的 [Serialization] 属性?
我认为处理这个问题的一个好方法是尝试执行自定义序列化逻辑,并且仅序列化您需要的内容,它不能达到 4GB,无论如何,它也取决于您的应用程序分配了多少内存。
你可以下载 JSON.NET 在我的项目中工作的库超过 100 MB 数据的序列化和反序列化。
对于序列化,你可以像这样工作
如果您有对象,请使用 TextWriter
using (TextWriter textWriter = File.CreateText("LocalJsonFile.json"))
{
var serializer = new JsonSerializer();
serializer.Serialize(textWriter , yourObject);
}
如果您有字符串,请使用 StringWriter
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using(JsonWriter textWriter = new JsonTextWriter(sw))
{
var serializer = new JsonSerializer();
serializer.Serialize(textWriter, yourObject);
}
这可能对你有用。