【发布时间】:2010-10-19 01:15:28
【问题描述】:
我编写了一个 .NET 应用程序,其中内存使用量随着时间的推移而增长。作为测试, 我将其设置为在 1 小时内以 15 分钟的间隔下载 800 * 5K(平均)大小的文件并进行 XML 转换并使用 DTComcontroller 生成清单。在大约 5 个小时的时间里,内存使用量从 35M 增长到大约 70M。
不确定这是否正常。我已经通过这样做来强迫它了
GC.collection();
GC.WaitForPendingFinalizers();
在每个工作循环结束时确保及时释放内存。
我已经确保在使用后关闭文件句柄、清除流或其他资源。有些对象只是在函数内部使用本地引用,我假设它们将在本地函数结束时被丢弃并与 GC.collction() 一起消失。
此外,Memory Profiler (ANTS) 显示,在每个工作循环的末尾都没有我的应用程序命名空间的对象,也没有可用源代码的新对象。在每个工作循环中创建的对象的新实例基本上称为 RuntimeModule、RuntimeAssembly 和 DeviceContext。看起来我对此无能为力?
这基本上是我的第一个应用程序,它假设运行 24/7,我真的不太了解内存泄漏。很可能,我的应用程序中的内存使用仍然存在问题。我只是不知道在哪里看这个阶段。
另外,我不知道它是否相关,我正在使用 .net Trace/debug 来保存日志。猜猜值得尝试关闭日志以查看内存使用量的增长。
更新: 让它看起来像 sslstate 和 sslstream 以及类 Reference Explorer 中的其他类的循环引用。也不确定这是否是 ANTS 生成图中的圆引用,这是否意味着我的代码中某处实际上存在圆引用?
我通过重用同一个对象来创建 XMLtransform 和 Manifest 进行了一些更改,并在完成工作迭代结束时使用它们后手动将每个对象设置为 null。现在内存大大减少了,在工作时仍然会增加私有内存的使用量,但速度要慢得多。
我认为对于我的特殊情况——在一个工作圈内创建许多对象,并且每个数据都保存在一个工作线程中。如果我没有显式释放对象引用,让 .NET GC 这样做会导致应用程序使用大量内存,因为它大部分时间都在工作,并且 GC 可能永远不会有机会进行内务处理,除非应用程序已手动关闭,我必须手动进行对象释放。
@WeNeedAnswers:
XmlDocument doc = new XmlDocument();
XmlTextReader textReader = new XmlTextReader(dataFile);
textReader.Read();
doc.Load(textReader);
【问题讨论】:
-
应用永远不需要调用 GC.Collect。您不一定会提供帮助,而且很可能会使问题变得更糟。
-
如果我直接在Console.WriteLine("Hello world")这样的线程中使用字符串,并且线程继续运行,.NET最终会释放该字符串使用的内存吗?