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

fun*_*oom 4 memory-leaks system.diagnostics

摘要

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

  • 进程名称或进程ID
  • CPU阈值百分比.

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

我有两个班: ProcessMonitorProcessMonitorList

前者,包裹着System.Diagnostics.PerformanceCounter
后者是一个IEnumarable允许前者的列表式结构.

问题

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

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

调查到目前为止

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

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

情节变粗

不好意思只是说,哦,然后没有内存泄漏,我进一步调查,并发现(通过调试)以下代码行演示泄漏发生的位置,箭头显示确切的行.

_pc = new PerformanceCounter("Process", "% Processor Time", processName);
Run Code Online (Sandbox Code Playgroud)

以上是启动_pc的地方,并且是我ProcessMonitor班级的构造函数.

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

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

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

我的问题:

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

fun*_*oom 5

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

看来该NextValue方法调用

GC.SuppressFinalization();
Run Code Online (Sandbox Code Playgroud)

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

所以,我所做的就是IDisposable在我的所有课程上实施,特别是那个环绕的课程PerformanceCounter.

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

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