。网络越来越多内存问题
我有一个应用程序,它做了一堆文本解析。每次通过后,它会将一些信息吐出到数据库中,并清除所有内部状态。。网络越来越多内存问题
我的问题是在Windows任务管理器/资源监视器分配的memeory不断增长和增长。我已经使用.Net Mem Profiler做了一些配置文件,它看起来应该会下降。下面是来自分析器的屏幕截图:
但在任务经理每次使用后通过内存私人工作集增加。我希望内存随着它的使用而增长,然后在每次传递之后回到正常水平,这样我就可以继续运行这个东西。
有什么建议寻找什么或任何想法是什么原因造成的?
这力量.NET来收集所有未使用的对象从内存中,因此回收一些吧:
GC.Collect();
GC.WaitForPendingFinalizers();
但是它不需要释放内存到操作系统,所以私有字节可能不受影响。请记住,CLR充当托管应用程序的内存管理器。 – 2012-03-23 23:48:48
任务经理是不是你的应用程序实际上使用内存的准确表示。它更多地表示了为应用程序分配或计划了多少内存窗口 - 如果您的应用程序需要更多,Windows可以扩展此数量,但是如果您的应用程序需要更少,Windows可能不会重新分配此内存,直到另一个应用程序实际需要它..
我想你上面的是一个相当准确的表示你的应用程序实际上在做什么(即它没有泄漏)。
有没有办法通过.Net或编译标志告诉Windows为应用程序释放内存。当它运行时,我不介意使用其实际需要的一些内存。但是,一旦处理完一项工作,从Windows获取内存将会很好。 – 2012-03-23 23:56:34
有几件事情来检查有:
- 事件处理保持对象还活着,以确保如果该签约了事件的对象超出范围的对象之前发布它从退订事件事件以防止发布对象保留对其的引用。
- 确保您在实现IDisposable的任何对象上调用dispose。一般来说,实现IDisposable的对象包含需要特别整理的资源。
- 如果您引用了任何com对象,请确保您正确释放它们。
您不应该在生产代码中调用GC.Collect()
。
+1永远不会调用GC.Collect() – 2012-03-24 00:07:55
如果您确实有内存泄漏,您可以使用SOS debugging extension来尝试找到它。 This article也是一个很好的例子,并且更完整一点,那么我的答案将包括什么。
你可以在VS或WinDbg中使用它,唯一的区别是你如何加载DLL。对于Visual Studio,首先在项目属性的调试选项卡中启用非托管调试。当需要加载时,请在Immediate Window
中使用.load SOS.dll
。对于WinDbg,打开可执行文件或附加到进程,并加载它,使用.NET 4的.loadby sos clr
或使用2或3.5的.loadby sos mscorwks
。
让应用程序运行一段时间后,暂停它(全部中断)。现在你可以加载SOS。成功后,输入!dumpheap -stat
。这将列出每个类正在使用多少内存。如果这还不足以发现泄漏,我链接的另一篇文章将更深入地探讨如何定位内存泄漏。
其实,我想我读错了图,所以你可能没有一个(除非我再读错了D :)。我想我可以把它放在这里,以防万一它适合其他人的记忆问题。 – Timiz0r 2012-03-24 00:30:15
解决此问题的一种方法是将您的工作分解为单独的可执行程序。一旦程序完成其工作并结束,所有的内存将被系统回收。
您是否遇到内存不足的问题?或者这只是先发制人的担忧? :) .net喜欢坚持记忆一段时间......我在这里没有看到任何异常。除非它真的引起问题,否则我不会太担心。 – cHao 2012-03-23 23:40:33
我有大量的导入作业,它们在聚集它并将其放入SQL之前使用一些内存。在做了其中的一些之后,它最终会吃掉系统中的所有内存并停止工作。 – 2012-03-23 23:55:21
你能发布跟踪显示每一代的堆利用率和堆中的实例吗?如果您使用小样本数据进行测试并比较每次传递后的内存快照,将会更容易。 – 2012-03-24 06:53:31