C#内存泄漏?

我有一个C#应用程序循环遍历数据表,并将它们推送到某些位置,如Sage和SQL表。

虽然它曾经工作得很好,但是在运行它一小时左右后,我莫名其妙地得到了Out of Memoryexception。 我注意到在任务管理器中,内存使用量每秒增加约1mb,并继续运行!

我的印象是垃圾收集会占用任何东西,但是为了确保我确保在使用它之后处理任何对象。 我知道没有代码就很难诊断,但是它有很多,而且我正在寻找更多的一般建议。

但是为了确保我确保在使用它们之后处理任何物体

Dispose()与内存管理或泄漏没有直接关系。

您将不得不寻找仍然“可达”的未使用对象。 使用内存分析器找出答案。

您可以从免费的CLR-Profiler开始 。

我想到了一些潜在的问题:

  1. 有一大堆对象无法用于垃圾收集(即它们仍然“可达”)。 例如,如果在每个循环中向列表添加一个对象,那么列表将无限增长,并且只要该列表仍可访问,列表中的每个元素仍将无法识别垃圾收集。 我并没有声称这就是正在发生的事情,这只是一个如何分配内存然后不被收集而留下的例子。
  2. 由于某种原因,垃圾收集器没有进行收集。
  3. 高内存使用实际上是由于您在应用程序中使用的非托管组件(例如,通过P / Invoke或COM互操作)。

如果没有看到任何代码,就如何解决问题提出具体建议是棘手的,但阅读调查内存问题应该给你一些关于如何自己诊断内存问题的指示。 特别是我的第一步可能是检查性能计数器以查看垃圾收集器是否实际运行,并检查各种堆大小。

请注意, DisposeIDisposable接口与内存使用无关 – 一旦完成它们就很难处理数据库连接等对象,因为它释放了任何相关资源(例如句柄),但是处理实现IDisposable的对象是不太可能的对内存使用有影响。

垃圾收集只能删除不再引用的对象。 此外,它只能摆脱托管对象 – 它无法控制从您可能正在连接的本机代码创建的内存。 因此,这些是C#代码中内存泄漏的两个根本原因。

首先要看的是perfmon。 获取进程的专用字节和.net堆大小的计数器。 如果堆大小保持不变(或上升和下降),但私有字节不断增加,你有一些本机代码分配内存而不释放它。

如果堆大小只是持续增长,那么泄漏就在你的托管代码中,你需要一个像ANTS,DotTrace甚至WinDbg(带有SOS扩展名)的分析器来检查堆并查看正在放置的对象。

.Net平台上最受欢迎的“内存泄漏”是在一些无限循环中重复添加的被遗忘的集合。

当你为临时记忆使用新东西。

始终使用以下方式,确保呼叫处理。

 using (Someclass A = new Someclass()) { ....something about A } 

Someclass是一个类实现的接口IDisposable

如果涉及某些不安全代码的部分(P / Invoke,Com等),GC将无法保存您,并且如果仍存在某个引用,则存在。

如果发现内存泄漏,使用WinDbg将会看到堆中的内容。

这篇文章可能会给你一些帮助。

http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx