【问题标题】:Serialization OutOfMemoryException序列化 OutOfMemoryException
【发布时间】:2013-11-18 13:26:15
【问题描述】:

我有一个程序,它将基于 xml 的大型结构构建到类中,并将它们保存在要序列化的集合中……将它们称为合同。每个合约都进入集合并由代表 XML 文档中节点的对象组成。这一切都很好,花花公子,但现在我们的收藏品达到了 10000 件。任务管理器仍然让我们在 8 GB 机器上的使用量达到 586 兆。

当我序列化到一个文件时,问题就来了:

        XmlSerializer serializer = new XmlSerializer(typeof(PolicyExtract));
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("ent", "http://xxxxxx.com/V2.0/enrollmententities");

        StreamWriter fs = new StreamWriter(filePath);
        serializer.Serialize(fs, this, ns);

        fs.Close();

这是类或集合本身。该文件很大(如预期的那样),但不足以占用所有内存。此时我收到System.OutOfMemoryException 并且根本没有生成任何文件。

所以回顾一下,我正在尝试将一个大型集合(仍然在内存限制范围内)序列化到一个文件中,并收到一个 OutOfMemoryException 并且没有文件。

有什么想法吗?

【问题讨论】:

  • 一个 32 位进程,即使在 64 位机器上也只能访问最大 3GB - 确保您以 64 位运行该进程。
  • ...每个对象实例只有 2GB,即使在 64 位机器上也是如此。
  • @SriramSakthivel - 默认情况下,2GB,带有某些操作系统启动开关,3GB。实际地址空间为 4GB,但并非全部可用。
  • @Oded 啊,我错过了最大这个词.. NVM
  • 我可以想象 XmlSerializer 有相当大的内部开销。如果你达到了它的极限,或者像其他评论员所说的那样增加记忆;或手动编写集合开始/结束标签,并使用 XmlSerializer 仅用于项目的序列化。

标签: c# xml serialization out-of-memory


【解决方案1】:

在反序列化大型 XML 文件 (> 1.4 GB) 时,我们在相反的方向遇到了类似的问题。在达到进程限制之前,我们也遇到了 OutOfMemoryExceptions。
我也喜欢 XML 序列化的简单性,但在处理大量数据的情况下,需要对序列化过程进行更多控制,因为 XML 处理通常与在内存中创建的大量字符串相关联。
经过数千次迭代,我们能够使用 XmlReader 和调用 GC.Collect 解决我们的问题。在您的情况下,使用XmlWriter 写入数据并在一些迭代后抛出 GC.Collect 也应该可以缓解问题。您需要多久调用一次垃圾收集器取决于您的场景,并且可能涉及一些试验和错误。不要太频繁地调用它,因为它是一个重量级的操作。
此外,您应该检查您的数据结构是否存在您可以通过方法替换的重复数据。
缺点当然是序列化代码变得更长并且更不容易处理,因为您可能需要在序列化代码中反映数据结构的变化。

【讨论】:

    【解决方案2】:

    转到您的项目属性 -> 构建选项卡 -> 平台目标:将“任何 CPU”更改为“x64”(假设您的电脑支持它)

    【讨论】:

    • 为此您需要 64 位基础架构。知道您收到哪个异常会很有用...
    猜你喜欢
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    相关资源
    最近更新 更多