C# .Net不断增长的内存问题

C# .Net不断增长的内存问题,c#,.net,windows,memory-management,memory-leaks,C#,.net,Windows,Memory Management,Memory Leaks,我有一个应用程序,它可以进行大量的文本解析。每次通过后,它都会向数据库中吐出一些信息,并清除所有内部状态 我的问题是Windows任务管理器/资源监视器中分配的内存不断增长。我已经用.Net Mem Profiler做了一些配置文件,它看起来应该会下降。以下是探查器的屏幕截图: 但在任务管理器中,每次通过后,内存专用工作集都会增加。我希望内存能随着使用量的增加而增长,然后在每次通过后恢复到正常水平,这样我就可以让它继续运行 关于寻找什么的任何建议或是什么原因的任何想法?这迫使.NET从内存中收

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

我的问题是Windows任务管理器/资源监视器中分配的内存不断增长。我已经用.Net Mem Profiler做了一些配置文件,它看起来应该会下降。以下是探查器的屏幕截图:

但在任务管理器中,每次通过后,内存专用工作集都会增加。我希望内存能随着使用量的增加而增长,然后在每次通过后恢复到正常水平,这样我就可以让它继续运行


关于寻找什么的任何建议或是什么原因的任何想法?

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

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

Task Mgr不是应用程序实际使用的内存的准确表示。它更多的是表示windows为您的应用程序分配或计划了多少内存-如果您的应用程序需要更多内存,windows可以扩展此数量,但如果您的应用程序需要更少内存,windows可能不会重新分配此内存,直到另一个应用程序实际需要它


我认为上面的内容非常准确地反映了应用程序的实际运行情况(即,它没有泄漏)。

需要检查的几件事是:

  • 事件处理程序使对象保持活动状态,确保如果订阅事件的对象在对象发布事件之前超出范围,则取消订阅该事件,以防止发布对象保留对其的引用
  • 确保对实现IDisposable的任何对象调用dispose。一般来说,实现IDisposable的对象包含需要特别整理的资源
  • 如果引用任何com对象,请确保正确释放它们

  • 您不应该在生产代码中调用
    GC.Collect()

    如果确实存在内存泄漏,可以使用来尝试查找它。这也是一个很好的例子,比我的答案要完整一些

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


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

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

    您是否遇到过内存不足的问题?或者这只是先发制人的担忧?:)。net喜欢保留一段时间的记忆……我在这里没有看到任何不寻常的东西。除非它真的引起了问题,否则我不会太担心它。我有一些大型导入作业,在它们聚合并将其放入SQL之前,它们会使用一些内存。在做了几次之后,它最终消耗了系统上的所有内存并停止工作。您可以发布跟踪,显示每一代中的堆利用率和堆中的实例吗?如果使用小样本数据进行测试,并在每次通过后比较内存快照,则测试将更容易。请检查这是否有帮助:但无需将内存释放到操作系统,因此专用字节可能不会受到影响。请记住,CLR充当托管应用程序的内存管理器。是否有方法通过.Net或编译标志通知windows释放应用程序的内存。当它运行的时候,我不介意它使用一些内存作为它的实际需要。但是一旦一个作业被处理了,从windows中恢复内存就好了。事实上,我猜我看错了图形,所以你可能没有一个(除非我再次看错了D:)。我想我可以把它放在这里,以防它对其他人的记忆问题有用。