2012-02-19 205 views
3

我一直在跟踪海量应用程序中的大量内存泄漏,看起来问题在于MemoryStream类。无论何时我使用“使用”关键字或明确的关闭/处理,内存将永远不会被垃圾收集器收集。这里有什么问题?C#MemoryStream泄漏内存,处理/关闭/ etc后?

byte[] bData = System.IO.File.ReadAllBytes("F:\\application_exit_bw.png"); 
using(System.IO.MemoryStream hMemoryStreamOutput = new System.IO.MemoryStream()) 
{ 
    for (int i = 0; i < 10000; i++) hMemoryStreamOutput.Write(bData, 0, bData.Length); 
} 
Thread.Sleep(Timeout.Infinite); 

使用明确的close/dipose行为保持不变。内存被占用,并保持这种状态,直到我关闭我的应用程序,或者,应用程序填满了所有的系统内存。帮帮我?

回答

1

问题的另一面是您正在使用,以确定“内存泄漏”的东西。有测量许多不同的方式“免费”的记忆,并根据它,你可能会得到tottaly不同的结果,在任务管理器

  • 内存使用展示 - 不可能往下走,即使所有的记忆被认为是‘自由’的CLR GC由于道路GC使用内存
  • GC内存性能计数器(和财产) - 。这些的居然会显示GC对内存视图你想用它来检测管理内存泄漏

有MemoryStream(和任何其他大型86K +)分配还有一件事 - 它们使用大对象堆,只能在完整G C,要触发它,您可能需要运行GC.Collect两次。在正常的应用程序流程中,它会发生足够的变化,因此在应用程序关闭之前您可能看不到此内存已释放。诊断 - 检查GC采集性能计数器(GC数量)。

还有一:如果你正在试图解决内存泄漏,因为你得到“内存不足”异常可以通过地址空间碎片引起的(通常仅适用于32位进程)。如果是这种情况 - 考虑创建自己的内存流,该内存流不会在单个块中分配内存,然后在增长流时不得不复制它。或者至少尝试预先分配流中的空间。

4

这是一个非确定性GC的症状。关于何时释放内存,GC不会保证任何。这是正常的,预期的和想要的行为。

尝试调用GC.Collect的(),看是否能解决您的问题。另外,您需要以释放模式运行,因为在调试模式下,JIT将局部变量的生存期延长到方法的末尾,即使它们在某点之后未被使用。

+2

+1的调试模式尖,感谢 – 2012-02-19 00:22:50

+0

请告诉我downvote呢?有什么不准确的地方?请报告错误,我会修复! – usr 2012-02-19 00:26:57

7

没有什么毛病MemoryStream类或示例代码中的用法。 .Net中的GC不再立即清除内存。相反,当堆中的可用空间达到某个阈值或通过GC.Collect调用显式调用它时,它会回收它。

在这种情况下,内存将被释放的唯一方法是GC在using声明之后和Thread.Sleep调用之前立即发生。这是相当不可能发生的,因此,如果您评测的程序,将有内存泄漏的外观时,它实际上没有泄漏

0

我已经使用这种方法进行批量处理

static byte[] buffer; 

    public static object Read(XmlDocument xmlDocument) 
    { 
     if (buffer == null) 
     { 
      buffer = new byte[1024 * 1024 * 512]; 
     } 

     if (xmlDocument != null) 
     { 
      using (MemoryStream ms = new MemoryStream(buffer)) 
      { 
       xmlDocument.Save(ms); 
       ms.Flush(); 
       ms.Seek(0, SeekOrigin.Begin); 

       object result = ReadFromStream(ms); 

       ms.Close(); 
       return result; 
      } 
     } 
     else 
     { 
      return null; 
     } 
    } 
0
调用

所以GC.Collect()是不是一个好的做法,并且不应该被用作溶液。

你可以试试,看看有没有改变任何东西,但不依赖于故意GC.Collect的()调用...