字符串似乎粘贴太久了

时间:2011-02-03 14:42:46

标签: c# string memory-management garbage-collection

简而言之,我有一个将平面数据文件转换为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();
          }
      }
}

4 个答案:

答案 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()方法?