如何解决System.Diagnostics.PerformanceCounter引起的内存泄漏问题

时间:2010-07-16 16:04:39

标签: memory-leaks system.diagnostics

摘要

我编写了一个进程监视器命令行应用程序,它将参数作为参数:

  • 流程名称或流程ID
  • CPU阈值百分比。

程序的作用是使用传递的名称或pid监视所有进程,如果它们的CPU使用率超过阈值%,则会杀死它们。

我有两节课: ProcessMonitorProcessMonitorList

前者围绕System.Diagnostics.PerformanceCounter包裹 后者是IEnumarable,允许前者的列表式结构。

问题

程序本身工作正常,但如果我在任务管理器上观察内存使用情况,它会以每秒约20kB的增量增长。注意:程序每秒通过PerformanceCounter轮询CPU计数器。

该程序需要在使用频繁的服务器上运行,并且正在监视大量进程。 (20-30)。

到目前为止的调查

我使用PerfMon来监控流程的私有字节所有堆中的字节总数,并根据下面引用的文章中提供的逻辑,我的结果表明,在波动时,该值仍然在可接受的范围内,因此没有内存泄漏:
Article

我还使用FxCop来分析我的代码,并没有提出任何相关的内容。

Plot Thickens

不满意只是说,哦,那时没有内存泄漏,我进一步调查,发现(通过调试)以下几行代码用箭头表明泄漏发生的位置显示确切的行。

_pc = new PerformanceCounter("Process", "% Processor Time", processName);

以上是_pc的启动位置,位于我的ProcessMonitor类的构造函数中。

以下是导致内存泄漏的方法。这个方法每隔一秒从我的主要调用。

public float NextValue()
{
        if (HasExited()) return PROCESS_ENDED;
        if (_pc != null)
        {
            _lastSample = _pc.NextValue();   //<-----------------------
            return _lastSample;
        }
        else return -1;
}

这向我表明泄漏存在于NextValue()方法内,该方法位于System.Diagnostics.PerformanceCounter类中。

我的问题:

  1. 这是一个已知的问题,我该如何解决它?
  2. 我的假设是任务管理器的内存使用量增加意味着确实存在内存泄漏问题吗?
  3. 是否有更好的方法来监控特定流程的多个实例,如果它们超过特定的阈值CPU使用率,则关闭它们,然后发送电子邮件?

1 个答案:

答案 0 :(得分:5)

所以我想我明白了。
使用Reflector工具,我能够检查System.Diagnostics内的代码。

NextValue方法似乎调用了

GC.SuppressFinalization();

这意味着(我想,如果我错了,请纠正)我需要在我的所有课程上明确地调用Dispose()

所以,我所做的就是在我的所有课程上实施IDisposable,尤其是围绕PerformanceCounter的课程。

我写了更明确的清除我的IList<PerformanceMonitor>和内部, 而且,记忆行为发生了变化。

它振荡,但内存使用量在很长一段时间内明显受限于可接受的范围。