2

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

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

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

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

编辑 :

  1. 我不使用自定义序列化,都是通过 [Serialization] 属性完成的。不包括某些字段。

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

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

  4. 我使用 XmlSerializer

PS我有4 GB的物理内存。

解决方案

感谢答案,我发现我的问题出在 XmlSerializer 上,我已经摆脱了它。二进制序列化与我拥有的数据一起工作得很好。

4

7 回答 7

3

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

我通过使用 Simon Hewitt 的优秀开源库解决了这个问题,请参阅Optimizing Serialization in .NET - part 2

除了显着减少内存使用量之外,它还更快。与文章类似,我得到了 20 倍的加速。

于 2009-08-17T21:23:18.747 回答
2

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

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

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

于 2009-04-02T12:34:49.013 回答
1

15MB 不应该给你一个 OOM。

如果数据是树状的(而不是完整的图),您可以考虑使用类似protobuf-net的序列化程序;除了使用谷歌非常高效(速度和内存)的二进制“协议缓冲区”格式外,它还受益于不必进行参考跟踪(图表需要)——这意味着它只需要担心一次数据(如果有,则两次)得到缓冲)。

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

于 2009-04-02T12:11:30.630 回答
0

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

于 2009-04-02T12:01:15.910 回答
0

也许你可以给我们更多关于如何进行序列化的细节。您是否使用自定义序列化?或者你只是使用内置的 [Serialization] 属性?

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

于 2009-04-02T12:02:03.070 回答
0

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

在对大型对象进行二进制格式化之前,还使用​​gzip7-Zip进行压缩,实际上会将 16 MB 以上的大小移动到 32 MB 左右。

于 2009-04-08T20:58:07.140 回答
0

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

这可能对你有用。

于 2016-11-07T07:06:38.120 回答