4

概括

我编写了一个以参数为参数的进程监视器命令行应用程序:

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

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

我有两个课程: ProcessMonitorProcessMonitorList

前者,环绕System.Diagnostics.PerformanceCounter
后者是一个IEnumarable允许前者的类似列表的结构。

问题

该程序本身运行良好,但是如果我在任务管理器上查看内存使用情况,它会以每秒约 20kB 的增量增长。PerformanceCounter注意:程序每秒轮询一次 CPU 计数器。

这个程序需要在一个使用率很高的服务器上运行,并且它正在监视大量的进程。(20-30)。

调查至今

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

我还使用 FxCop 来分析我的代码,但它没有提出任何相关的信息。

情节变厚了

不习惯只是说,​​哦,那么没有内存泄漏,我进一步调查,发现(通过调试)以下代码行显示了泄漏发生的位置,箭头显示了确切的行。

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

以上是 _pc 启动的地方,并且在我的ProcessMonitor类的构造函数中。

以下是导致内存泄漏的方法。每秒都会从我的 main 调用此方法。

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 使用率时将其关闭,然后发送电子邮件?
4

1 回答 1

7

所以我想我想通了。
使用Reflector工具,我能够检查System.Diagnostics.

看来该NextValue方法调用

GC.SuppressFinalization();

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

所以,我所做的是IDisposable在我所有的类上实现,尤其是那些围绕PerformanceCounter.

我写了更明确的清理我IList<PerformanceMonitor>的,内部结构,瞧,内存行为改变了。

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

于 2010-07-17T15:30:41.503 回答