.Net不断增长的记忆问题

时间:2012-03-23 23:36:31

标签: c# .net windows memory-management memory-leaks

我有一个应用程序可以进行大量的文本解析。每次传递后,它会将一些信息吐出到数据库中并清除所有内部状态。

我的问题是Windows Task Mgr / Resource Monitor中分配的记忆不断增长和增长。我使用.Net Mem Profiler完成了一些配置文件,它看起来应该会失败。以下是分析器的屏幕截图:

enter image description here

但是在每次传递后的Task Mgr中,内存私有工作集会增加。我希望内存随着它的使用而增长,然后在每次传递后恢复到正常水平,这样我就能保持这个东西的运行。

有关寻找什么或任何想法的建议是什么?

5 个答案:

答案 0 :(得分:4)

要检查的一些事项是:

  1. 事件处理程序使对象保持活动状态,确保如果订阅事件的对象在发布事件的对象之前超出范围,它将从事件中取消订阅,以防止发布对象保留对它的引用。
  2. 确保在任何实现IDisposable的对象上调用dispose。一般来说,实现IDisposable的对象包含需要特殊整理的资源。
  3. 如果您引用任何com对象,请确保正确释放它们。
  4. 您不应该在生产代码中调用GC.Collect()

答案 1 :(得分:3)

任务管理器不能准确表示应用程序实际使用的内存。它更多地表示为您的应用程序分配或计划了多少内存窗口 - 如果您的应用程序需要更多,Windows可以扩展此数字,但如果您的应用程序需要更少,Windows可能不会重新分配此内存,直到另一个应用程序实际需要它..

我认为您上面的内容非常精确地表示了您的应用程序实际执行的操作(即,它没有泄漏)。

答案 2 :(得分:1)

这迫使.NET从内存中收集所有未使用的对象,从而回收其中的一些:

GC.Collect();
GC.WaitForPendingFinalizers();

答案 3 :(得分:1)

如果您确实有内存泄漏,可以使用SOS debugging extension尝试查找内存。 This article也是一个非常好的例子,比我的回答更为完整。

您可以在VS或WinDbg中使用它,唯一的区别是您加载DLL的方式。对于Visual Studio,首先在项目属性的调试选项卡中启用非托管调试。在加载时,请使用.load SOS.dll中的Immediate Window。对于WinDbg,要么打开可执行文件要么附加到进程,要加载它,请使用.loadby sos clr表示.NET 4或.loadby sos mscorwks表示2或3.5。

让应用程序运行一段时间后,暂停它(全部中断)。现在您可以加载SOS。成功后,输入!dumpheap -stat。这将列出每个类使用的内存量。如果这还不足以找到泄漏,我链接的另一篇文章将更深入地介绍如何找到内存泄漏。

答案 4 :(得分:0)

解决此问题的一种方法是将您的工作分解为单独的可执行程序。一旦程序完成其工作并结束,系统将回收其所有内存。