fun*_*oom 4 memory-leaks system.diagnostics
我编写了一个进程监视器命令行应用程序,它将参数作为参数:
该程序的作用是使用传递的名称或pid监视所有进程,如果它们的CPU使用率超过阈值%,则会杀死它们.
我有两个班:
ProcessMonitor和ProcessMonitorList
前者,包裹着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类中.
所以我想我明白了.
使用Reflector工具,我能够检查内部的代码System.Diagnostics.
看来该NextValue方法调用
GC.SuppressFinalization();
Run Code Online (Sandbox Code Playgroud)
这意味着(我想,如果我错了,请纠正)我需要明确地调用Dispose()我的所有课程.
所以,我所做的就是IDisposable在我的所有课程上实施,特别是那个环绕的课程PerformanceCounter.
我写了更明确的清理我IList<PerformanceMonitor>的内部和内部,并且记忆行为发生了变化.
它会振荡,但内存使用量在很长一段时间内明显受限于可接受的范围.