MemoryStream 对象抛出 System.OutOfMemoryException

问题描述

我有这段代码,它在我的机器上运行良好,但在另一台机器上抛出 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有几个问题,但没有回答我的问题。

我尝试过的事情:

  • constructors 的所有 MemoryStream

  • MemoryTributary.cs

    MemoryStream 流 = new MemoryStream(); 线程睡眠(4000); //由于最后一点添加了这个。 xDoc.Save(stream); 流。位置= 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 语句的原因

谢谢

解决方法

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

ToString() 起作用而 Save() 不起作用的可能原因是,每次流通过缓冲区末尾时,MemoryStream 都会将其缓冲区加倍。因此,您保留的不仅仅是一个 60MB 的连续内存块,而是多个大小每次增加一倍的块,最多可达 60MB。这些将位于不会像普通堆一样压缩的大对象堆上。