Memory leaks 如何解决System.Diagnostics.PerformanceCounter导致的内存泄漏 总结

Memory leaks 如何解决System.Diagnostics.PerformanceCounter导致的内存泄漏 总结,memory-leaks,system.diagnostics,Memory Leaks,System.diagnostics,我已经编写了一个进程监视器命令行应用程序,它采用以下参数: 进程名称或进程ID CPU阈值百分比 该程序所做的是监视具有传递名称或pid的所有进程,如果它们的CPU使用率超过阈值%,则会杀死它们。 我有两门课: ProcessMonitor和ProcessMonitorList 前者围绕着System.Diagnostics.PerformanceCounter 后者是一个IEnumarable,允许前者具有类似列表的结构。 问题 程序本身运行良好,但是如果我在TaskManager上观察内

我已经编写了一个进程监视器命令行应用程序,它采用以下参数:

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

我有两门课:
ProcessMonitor
ProcessMonitorList

前者围绕着
System.Diagnostics.PerformanceCounter

后者是一个
IEnumarable
,允许前者具有类似列表的结构。

问题 程序本身运行良好,但是如果我在TaskManager上观察内存使用情况,它会以每秒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;
}
public float NextValue()
{
如果(HasExited())返回过程结束;
如果(_pc!=null)
{

_lastSample=_pc.NextValue();//所以我想我已经找到了答案。
使用该工具,我能够检查
System.Diagnostics
中的代码

似乎
NextValue
方法调用了

GC.SuppressFinalization();
这意味着(我想,如果我错了,请纠正)我需要在所有类上显式调用
Dispose()

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

我对我的
IList
和内部代码编写了更明确的清理, 瞧,记忆行为改变了


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

如果运行程序一段时间,内存使用量是否会继续增加?比如说5、10、20分钟?是的,内存使用量会继续增加,并且变得非常大。我将收集一些统计数据5分钟,然后发布。从我收集的统计数据中可以看出,t它增长到5k左右,然后下降到4k,然后增长到5k等,并继续这种行为(可接受),因此我认为这不再是一个问题您是对的,PerformanceCounter实现IDisposable。您需要调用Close、将计数器变量包装在using语句中或调用Dispose来释放共享资源。请参阅:使用PerformanceCounterCategory和调用GetCounters()时也要小心。它返回PerformanceCounter对象的列表,您也必须处理所有这些对象。