简而言之,我有一个将平面数据文件转换为XML文件的应用程序。它通过填充对象然后将它们序列化为XML来实现此目的。
我遇到的问题是垃圾收集器似乎没有处理序列化的字符串。 3500个记录文件在完成之前运行到OutOfMemoryExceptions。确实有点可疑。
当我从混合中取出序列化并简单地传递一个空字符串时,内存消耗仍然如预期一样,所以我排除了我的中间对象(在平面文件和xml之间)是问题的可能性。它们似乎按预期收集。
有人可以帮忙吗?如何确保正确处理这些字符串?
更新:一些示例代码
// myObj.Serialize invokes an XmlSerializer instance to handle its work
string serialized = myObj.Serialize();
myXmlWriter.WriteRaw(serialized);
这基本上就是问题出现的地方 - 如果我把字符串serialized
带出游戏,内存问题也会消失,即使我仍在将平面文件转换为对象,一时间
更新2:序列化方法
public virtual string Serialize()
{
System.IO.StreamReader streamReader = null;
System.IO.MemoryStream memoryStream = null;
using (memoryStream = new MemoryStream())
{
memoryStream = new System.IO.MemoryStream();
Serializer.Serialize(memoryStream, this);
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
using (streamReader = new System.IO.StreamReader(memoryStream))
{
return streamReader.ReadToEnd();
}
}
}
答案 0 :(得分:2)
您需要确保它们不会被引用到任何地方。在抛出OutOfMemoryException之前,运行GC。如果它没有恢复那个记忆,那意味着还有一些东西仍然存在。像其他人说的,如果你发布一些代码,我们可能会提供帮助。否则,您可以使用分析器或WinDbg / SOS来帮助弄清楚字符串上的内容。
答案 1 :(得分:1)
确实非常好奇。在每个序列化记录写入XmlWriter之后,我添加了以下花花公子:
if (GC.GetTotalMemory(false) > 104857600)
{
GC.WaitForPendingFinalizers();
}
并且你不知道它,它正在检查它并且它没有发生事故处理,从未超过我设置的阈值。我觉得应该有更好的方法,但几乎看起来代码执行速度太快,垃圾收集器无法及时回收字符串。
答案 2 :(得分:0)
您是否有代码示例 - 您是如何创建这些字符串的?您是否在任何地方突破了非托管代码(这意味着您需要自行清理)。
另一个想法是如何将平面数据文件转换为XML。 XML可能有点沉重,具体取决于您构建文件的方式。如果你试图将整个对象保存在内存中,那么很可能(实际上很容易做到)你内存不足。
答案 3 :(得分:0)
看起来你的方法看起来很简单:
public virtual string Serialize()
{
StringBuilder sb = new StringBuilder();
using (StringWriter writer = new StringWriter(sb))
{
this.serializer.Serialize(writer, this);
}
return sb.ToString();
}
您无缘无故地创建了额外的MemoryStream
。
但是,如果您要将字符串写入文件,那么为什么不将FileStream
发送到Serialize()
方法?