C# MemoryStream对象引发System.OutOfMemoryException

C# MemoryStream对象引发System.OutOfMemoryException,c#,memory,out-of-memory,messagebox,C#,Memory,Out Of Memory,Messagebox,我有一段代码,它在我的机器上运行良好,但在另一台机器上抛出System.OutOfMemoryException。我只是尝试初始化MemoryStream对象,然后在其中写入xDoc的内容。 xDoc是数据类型XDocument的对象,在我的机器中,我可以看到当使用xDoc的内容写入时,流的长度是58070847 MemoryStream stream = new MemoryStream(); xDoc.Save(stream); stream.Position = 0; using (var

我有一段代码,它在我的机器上运行良好,但在另一台机器上抛出
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();
}
这里有几个关于
系统的问题。OutOfMemoryException
,但它们没有回答我的问题

我尝试过的事情:

  • 内存流的所有
    构造函数

  • MemoryStream stream=新的MemoryStream(); 睡眠(4000)//添加此项是因为最后一点。 xDoc.Save(流); 流位置=0; 使用(var sr=新的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的两倍。它们将位于大型对象堆上,而该堆的压缩方式与普通堆不同。

它在哪里引发异常?在
Save
ReadToEnd
中?当您应该能够只执行
strXml=xDoc.ToString()时,不清楚为什么这里会涉及
MemoryStream
?@Damien\u不信者我知道这可以通过你建议的简单行完成,但我更感兴趣的是我在给定的代码段中做错了什么,这样我才能更好地理解C。@JonSkeet in
Save
人们为什么这样做?在他们的头脑中,谁认为在一段代码中添加60MB的XML是可以的?您的代码需要在连续内存中使用其倍数来保存字符串、内存流中的字节数组等。您可能正在以32位进程的形式运行。解决方案不是切换到64位,而是给发送此XML的人一记耳光。感谢您的解释,还有一个后续问题:为什么它在我的机器上工作,而不是在另一台具有相同配置的机器上工作。这一切取决于机器有多少内存,还有什么在运行,托管堆处于什么状态等。即使
ToString()
有时也会引发异常,因此是否有一种优化的方法来初始化
strXml
?问题是将整个序列化文档同时保存在内存中。你真的需要所有的记忆吗?XDocument,Save()有一个接受流的重载。您可以将流传输到磁盘或网络吗?