概括

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

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

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

    我有两个类(class):ProcessMonitorProcessMonitorList
    前者,环绕 System.Diagnostics.PerformanceCounter后者是一个 IEnumarable,它允许前者的类似列表的结构。

    问题

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

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

    调查至今

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

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

    情节变厚

    不舒服只是说,哦,那么没有内存泄漏,我进一步调查,发现(通过调试)以下代码行演示了泄漏发生的位置,箭头显示了确切的行。
    _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 类中。

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

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

    似乎 NextValue 方法调用

    GC.SuppressFinalization();
    

    这意味着(我认为,如果我错了,请纠正)我需要在我的所有类上显式调用 Dispose()

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

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

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

    关于memory-leaks - 如何解决 System.Diagnostics.PerformanceCounter 导致的内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3266777/

    10-12 00:42
    查看更多