我在应用程序中使用序列化来实现“保存”功能。但是,当数据太大(15+ MB)时,我开始出现 OutOfMemory 异常。

我有很多对象,并且它们与其他小对象连接,我认为这导致内存中保存的处理能力和数据过多。

我的代码基于此,几乎相同:

http://www.codeproject.com/KB/vb/TreeViewDataAccess.aspx

编辑 :

  1. 我不使用自定义序列化,这一切都是由 [Serialization] 属性完成的。排除某些字段。

  2. 我序列化了很多对象和自定义类。包括字典、结构和一堆其他东西。

  3. 我将它序列化到一个文件中。

  4. 我使用 XmlSerializer

附:我有 4 GB 物理内存。

解决方案

感谢答案,我发现问题出在 XmlSerializer 上,我已经解决了它。二进制序列化对于我所获得的数据运行得很好。

有帮助吗?

解决方案

15MB 不应该给你带来 OOM。

如果数据是树状的(而不是完整的图),您可能会考虑像这样的序列化器 protobuf网络;以及使用谷歌非常高效(速度和内存)的二进制“协议缓冲区”格式,它受益于不必进行参考跟踪(图形所需) - 这意味着它只需要担心数据一次(如果有两次)得到缓冲)。

但是,这需要对您的类进行不同的标记(或者至少是“选择加入”),并且它无法处理完整的图表。但它就在那里,而且免费......

其他提示

我有完全相同的问题。原因是.NET序列化不会扩展。

我通过使用Simon Hewitt出色的开源库解决了问题,请参阅 优化.NET中的序列化 - 第2部分.

除了大大减少内存使用情况外,它的速度也更快。与文章类似,我得到了 20 倍的加速。

实际上,XmlSerializer 会忽略 SerializedAttribute 属性。它们仅由格式化类(BinaryFormatter、SoapFormatter)使用。

我不会使用 XmlSerializer 进行序列化,尤其不会使用 XmlSerializer 和 BinaryFormatter 的组合。

我只是尝试使用 BinaryFormatter 序列化所有内容。

您可以编写自己的序列化例程,并查看是否可以通过手动定制序列化过程来获得任何性能优势。有关更多详细信息,请参阅 有关自定义序列化的 MSDN 页面.

也许您可以向我们提供有关如何进行序列化的更多详细信息。您使用自定义序列化吗?或者您只使用内置的 [Serialization] 属性?

我认为处理这个问题的一个好方法是尝试执行自定义序列化逻辑,并且仅序列化您需要的内容,它不能达到 4GB,无论如何,它也取决于您的应用程序分配了多少内存。

使用此处提到的所有方法,都失去了将大对象转储到磁盘和恢复的便利性。此外,这些仅支持转储数据类型,因此您无法像使用 BinaryFormatter 那样轻松转储引用类型。

还使用进行压缩 压缩包 或者 7-拉链 在对大对象进行二进制格式化之前,实际上会将 16 MB 以上的大小移动到 32 MB 左右。

你可以下载 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);
  }

这可能对你有用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top