【发布时间】:2016-10-18 07:10:27
【问题描述】:
我正在管理一个大型项目,需要以 xml 格式序列化和发送对象。该对象约为 130 mb。
(注意:我没有写这个项目,所以在这个方法之外进行编辑,或者彻底改变架构不是一种选择。它正常工作很好,但是当对象这么大时,它会抛出内存不足异常. 我需要用另一种方式来处理大物体。)
目前的代码是这样的:
public static string Serialize(object obj)
{
string returnValue = null;
if (null != obj)
{
System.Runtime.Serialization.DataContractSerializer formatter = new System.Runtime.Serialization.DataContractSerializer(obj.GetType());
XDocument document = new XDocument();
System.IO.StringWriter writer = new System.IO.StringWriter();
System.Xml.XmlTextWriter xmlWriter = new XmlTextWriter(writer);
formatter.WriteObject(xmlWriter, obj);
xmlWriter.Close();
returnValue = writer.ToString();
}
return returnValue;
}
它在 returnValue = writer.ToString() 处抛出内存不足异常。
我重写了它以使用我更喜欢的“使用”块:
public static string Serialize(object obj)
{
string returnValue = null;
if (null != obj)
{
System.Runtime.Serialization.DataContractSerializer formatter = new System.Runtime.Serialization.DataContractSerializer(obj.GetType());
using (System.IO.StringWriter writer = new System.IO.StringWriter())
{
using (System.Xml.XmlTextWriter xmlWriter = new XmlTextWriter(writer))
{
formatter.WriteObject(xmlWriter, obj);
returnValue = writer.ToString();
}
}
}
return returnValue;
}
对此进行研究,似乎 StringWriter 上的 ToString 方法实际上使用了两倍的 RAM。 (实际上我有很多可用的 RAM,超过 4 GB,所以我不确定为什么会出现内存不足错误)。
【问题讨论】:
-
应用程序是为“x86”、“x64”还是“任何 CPU”构建的。如果构建平台是 x86,那么您的 .net 应用程序将作为 32 位进程运行,尽管您有 64 位环境并且如果它作为 x64 运行,则可以访问更多内存。
-
这是 x86,我无法更改。但是,它仍然是一个 130 兆的对象,所以无论哪种方式,它都不会超过 x86 内存限制。
-
在 32 位上,您可以分配多少 连续 内存的实际限制远小于 2GB 的理论限制。例如,请参阅stackoverflow.com/questions/2415434/…。您可以对此代码进行哪些更改?你必须返回一个字符串吗?会不会是别的?
-
不要使用
StringWriter。不要返回字符串。使用FileStream,直接写入即可。 -
我经常看到类似这样的代码:大量的数据被序列化成一个字符串,然后这个字符串在方法之间反复传递。我的头发从它竖立起来! .NET 中的字符串是按值复制的。天啊!以垃圾收集器、CPU 周期和 John Skeet 的名义,把 g-string 留给女孩们!
标签: c# serialization out-of-memory xmltextwriter stringwriter