繁体   English   中英

C#内存泄漏?

[英]C# memory leak?

我有一个C#应用程序,该应用程序循环遍历数据表,并将这些表推入Sage和SQL表等某些位置。

尽管它过去可以正常工作,但运行一个小时左右后,我现在莫名其妙地遇到了内存不足异常。 我在任务管理器中注意到,内存使用量每秒增加约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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM