我编写了一个进程监视器命令行应用程序,它将参数作为参数:
程序的作用是使用传递的名称或pid监视所有进程,如果它们的CPU使用率超过阈值%,则会杀死它们。
我有两节课:
ProcessMonitor
和ProcessMonitorList
前者围绕System.Diagnostics.PerformanceCounter
包裹
后者是IEnumarable
,允许前者的列表式结构。
程序本身工作正常,但如果我在任务管理器上观察内存使用情况,它会以每秒约20kB的增量增长。注意:程序每秒通过PerformanceCounter
轮询CPU计数器。
该程序需要在使用频繁的服务器上运行,并且正在监视大量进程。 (20-30)。
我使用PerfMon来监控流程的私有字节与所有堆中的字节总数,并根据下面引用的文章中提供的逻辑,我的结果表明,在波动时,该值仍然在可接受的范围内,因此没有内存泄漏:
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类中。
答案 0 :(得分:5)
所以我想我明白了。
使用Reflector工具,我能够检查System.Diagnostics
内的代码。
NextValue
方法似乎调用了
GC.SuppressFinalization();
这意味着(我想,如果我错了,请纠正)我需要在我的所有课程上明确地调用Dispose()
。
所以,我所做的就是在我的所有课程上实施IDisposable
,尤其是围绕PerformanceCounter
的课程。
我写了更明确的清除我的IList<PerformanceMonitor>
和内部,
而且,记忆行为发生了变化。
它振荡,但内存使用量在很长一段时间内明显受限于可接受的范围。