2011-09-07 143 views
0

我有一个C#应用程序循环通过一个数据表,并将它们推入一些位置,如Sage和一个SQL表。C#内存泄漏?

虽然它用于正常工作,但我现在莫名其妙地在运行一小时左右后出现内存不足异常。我已经注意到在任务管理器中,内存使用量每秒增加大约1mb,并且一直在继续!

我的印象垃圾收集会带来任何东西,但要确保我确保在使用它们之后处置任何对象。我知道没有代码很难诊断,但是它有很多,我正在寻找更多的一般建议。

+0

什么版本的VS你有吗?有了*更好的*,你可以使用探查器来试着找出你推入堆的什么类型的对象 - 这将有很大的帮助。 – Carsten

+0

您是从您已经处理的DataTable中删除行吗? –

回答

3

但可以肯定我保证我用他们

的Dispose(处置后的任何对象)是没有直接关系的内存管理或泄漏。

您必须查找仍然“可到达”的未使用对象。使用内存分析器来查明。

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

2

有一对夫妇的涌现在脑海潜在的问题:

  1. 有那剩下inelegible垃圾收集对象的大池(即,它们仍然是“可达”)。例如,如果您在每个循环中将对象添加到列表中,那么列表将无限制地增长,并且只要该列表仍然可以访问,列表中的每个元素都将无法用于垃圾回收。我并不是说这就是发生了什么事,这只是内存如何分配然后离开而不被收集的例子。
  2. 由于某种原因,垃圾收集器没有进行收集。
  3. 高内存使用实际上是由于您在应用程序中使用了非托管组件(例如,通过P/Invoke或COM interop)。

没有看到任何代码的技巧就如何解决您的问题但是通过Investigating Memory Issues阅读应该给你如何给自己诊断内存问题的一些指针具体建议。特别是,我的第一步可能是检查性能计数器以查看垃圾收集器是否实际运行,并检查各种堆大小。

注意DisposeIDisposable接口无关内存使用 - 它的重要,因为它释放了所有相关资源,一旦你与他们进行处置,如数据库连接对象(如处理),但是配置实现IDisposable对象对内存使用不太可能产生影响。

1

垃圾收集只能摆脱不再引用其他任何东西的对象。此外,它只能摆脱托管的对象 - 它无法控制由您可能与之交互的本机代码创建的内存。因此这些是C#代码中内存泄漏的两个根本原因。

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

如果堆大小只是持续增长,那么泄漏是在您的托管代码中,您需要一个像ANTS,DotTrace或WinDbg(带SOS扩展)的分析器来检查堆并查看哪些对象在说谎。

1

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

0

当您为临时内存使用新内容时。

总是使用下面的方式,它确保调用处理。

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

SomeClass的是一个类实现的接口IDisposable的

GC也救不了你,如果有不安全的代码,某些部分参与(P/Invoke的,玉米等),如果还有一个参考有些地方存在。

如果发现内存泄漏,使用WinDbg将会看到堆中有什么。

本文可能会给你一些帮助。

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