【问题标题】:MemoryStream object throwing System.OutOfMemoryExceptionMemoryStream 对象抛出 System.OutOfMemoryException
【发布时间】:2021-05-20 06:34:17
【问题描述】:

我的这段代码在我的机器上运行良好,但在另一台机器上抛出了System.OutOfMemoryException。我只是想初始化MemoryStream 对象,然后在其中写入xDoc 的内容。 xDoc 是一个数据类型为 XDocument 的对象,在我的机器上我可以看到用 xDoc 的内容写入的流的长度是 58070847

MemoryStream stream = new MemoryStream();
xDoc.Save(stream);
stream.Position = 0;
using (var sr = new StreamReader(stream))
{
    strXml = sr.ReadToEnd();
}

System.OutOfMemoryException 这里有几个问题,但他们没有回答我的问题。

我尝试过的事情:

  • MemoryStream 的所有 constructors

  • MemoryTributary.cs

    MemoryStream 流 = new MemoryStream(); 线程.睡眠(4000); //添加这个是因为最后一点。 xDoc.Save(流); 流.位置 = 0; 使用 (var sr = new StreamReader(stream)) { strXml = sr.ReadToEnd(); }

以上都不起作用,但奇怪的是下面的代码起作用了,我想知道如何。

MemoryStream stream = new MemoryStream();
MessageBox.Show("Loading data"); //Added this for reference while testing and strangely doesn't throw any error!!
xDoc.Save(stream);
stream.Position = 0;
using (var sr = new StreamReader(stream))
{
    strXml = sr.ReadToEnd();
}

我想了解为什么添加 MessageBox 语句有效

谢谢

【问题讨论】:

  • 在哪里抛出异常?在SaveReadToEnd
  • 目前还不清楚为什么MemoryStream 会在这里涉及到,而您应该可以只做strXml = xDoc.ToString()
  • @Damien_The_Unbeliever 我知道这可以通过您建议的简单行来完成,但我更感兴趣的是我在给定的代码中做错了什么,以便我更好地理解 C#。
  • @JonSkeet In Save
  • 人们为什么要这样做?有谁会认为将 60 MB 的 XML 投入到一段代码中是可以的?您的代码将需要在连续内存中的倍数来保存字符串、内存流中的字节数组等。您可能正在作为 32 位进程运行。解决办法不是切换到 64 位,而是给发给你这个 XML 的人一巴掌。

标签: c# memory out-of-memory messagebox


【解决方案1】:

您正在使用大量连续的内存来在内存中保存序列化的 xml 文档。没有必要这样做。 xDoc 可以直接序列化到磁盘或从磁盘序列化,并且将保存更小的二进制表示。

ToString() 有效而Save() 无效的可能原因是,每次流通过缓冲区末尾时,MemoryStream 将其缓冲区加倍。因此,您要保留的不仅仅是一个 60MB 的连续内存块,而是多个块,每次大小都会翻倍,最高可达 60MB。这些将位于大型对象堆上,与普通堆不同。

【讨论】:

  • 感谢您的解释,还有一个后续问题:为什么它在我的机器上工作,而不是在另一台具有相同配置的机器上工作。
  • 一切都取决于机器有多少内存,还有什么正在运行,托管堆处于什么状态等。
  • 即使 ToString() 有时也会抛出异常,所以有没有优化的方法来初始化 strXml
  • 问题是一次将整个序列化文档保存在内存中。你真的需要在内存中吗? XDocument,Save() 有一个采用流的重载。您可以改为流式传输到磁盘或网络吗?
猜你喜欢
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多