.NET应用程序内存使用量随时间增长,内存泄漏与否?

时间:2010-10-19 01:15:28

标签: .net memory

我写了一个.NET应用程序,其中内存使用量随着时间的推移而增长。作为测试, 我将其设置为下载800 * 5K(平均)大小的文件并进行XML转换并使用DTComcontroller在1小时内生成清单,间隔为15分钟。在大约5个小时的时间内,内存使用量从35M增加到大约70M。

不确定这是否正常。我已经强迫它做了

GC.collection();
GC.WaitForPendingFinalizers();

在每个工作圈结束时,只是为了确保及时释放记忆。

我已经确定使用后关闭文件句柄,清除流或其他资源。有些对象只是在函数内部使用局部引用,我认为它们将在本地函数结束时被丢弃,并且与GC.collction()一起消失。

此外,Memory Profiler(ANTS)显示在每个工作循环的末尾没有留下我的应用程序命名空间的对象,也没有剩下源代码可用的新对象。在每个工作循环期间创建的对象的新实例基本上称为RuntimeModule,RuntimeAssembly和DeviceContext。看起来我不能做任何事情吗?

这基本上是我的第一个应用程序,假设每周7天,每天24小时运行,我真的不太了解记忆泄漏。更有可能的是,我的应用程序中仍然存在内存使用问题。我只是不知道在哪个阶段看这个阶段。

另外,我不知道它是否相关,我使用.net Trace / debug来保存日志。猜测是否值得尝试关闭日志以查看内存使用量的增长。

更新: alt text 看起来它看起来像sslstate和sslstream的圆引用以及Reference Explorer中的其他类。还不确定这是否是ANTS生成的图形中的圆形参考,这意味着我的代码中某处实际存在圆形参考?

我通过重复使用相同的对象进行XMLtransform和Manifest创建做了一些更改,并在完成在工作迭代结束时使用它们之后手动将每个Object设置为null。现在内存大大减少了,但仍在增加私有内存使用量,但速度很慢。

我认为对于我的特殊情况 - 在工作圈内创建大量对象,并且每个数据都保存在一个工作线程中。如果我没有明确地释放对象引用,那么让.NET GC这样做将导致应用程序使用大量内存,因为它在大多数时间都在保持工作,并且GC可能永远不会有可能做家务,除非应用程序已手动关闭,我必须手动更新对象。
@WeNeedAnswers:

            XmlDocument doc = new XmlDocument();
            XmlTextReader textReader = new XmlTextReader(dataFile);
            textReader.Read();
            doc.Load(textReader);

4 个答案:

答案 0 :(得分:2)

任务管理器向您显示属于应用程序的内存量,该内存恰好在当时(工作集)中被分页到实际内存中。这可能就是你所看到的。

如果您查看进程使用的“专用字节”,这应该可以更好地指示所使用的内存量。修剪过程工作集时,此值不会更改。 this Microsoft KB article中有更多信息。

您可以使用Win32 API调用SetProcessWorkingSetSize(GetCurrentProcess(), - 1,-1)手动减少应用的工作集。

当系统内存不足时,这就是Windows无论如何都要做的事情,但是控制何时发生这种情况会让你将.NET应用程序的工作集剥离到最小尺寸以便进行调查。

BTW,be very careful about calling GC.Collect()

答案 1 :(得分:1)

处理对象处理的惯用方法是IDisposable接口。这就是允许您使用using构造来确保释放对象的原因。 @Joe是对的;在大多数情况下,您不应直接调用垃圾收集器。

答案 2 :(得分:0)

  

我写了一个.NET应用程序   内存使用率正在不断增长。如   测试,我把它设置为下载800 *   5K(平均)大小的文件和做XML   转换和使用DTComcontroller   生成清单,在1小时内用   间隔15分钟。期间   大约5个小时的时间,内存使用量   从35M增长到大约70M。

这是一个问题吗?如果不是(即足够的记忆)可能是原因。 GC仅在内存开始变得稀缺时才起作用。一般恕我直言,70mb也很低。

答案 3 :(得分:0)

不是泄漏,它是一个功能。不要做GC.Collect是讨厌的。如果我的测试盒由于缺乏资源而倒下,我只会担心它是泄漏,而不是因为系统使用的内存比我预期的多。垃圾收集器在它真的存在之前不会运行。我认为你施加的压力不足以让它担心它。

如果您真的担心,请以更快的间隔将大量数据推入您的系统,看看会发生什么。如果它可以在突发模式下处理极端情况,那么通常当你移动到慢速涓流时它应该更优雅地处理它。请记住,调用GC.Collect的成本很高,所以当算法确定其必要时,Framework会调用它。

您是通过流枚举数据还是将其整理到内存中。如果前者比我的经验你获得了一致的记忆足迹。如果是后者,根据xml的大小,它可能会使龙骨过度。

相关问题