概括
我编写了一个进程监视器命令行应用程序,它将作为参数:
该程序的作用是使用传递的名称或 pid 监视所有进程,如果它们的 CPU 使用率超过阈值%,它将杀死它们。
我有两个类(class):
ProcessMonitor
和 ProcessMonitorList
前者,环绕
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 类中。我的问题:
最佳答案
所以我想我想通了。
使用 Reflector 工具,我能够检查 System.Diagnostics
中的代码。
似乎 NextValue
方法调用
GC.SuppressFinalization();
这意味着(我认为,如果我错了,请纠正)我需要在我的所有类上显式调用
Dispose()
。所以,我所做的是在我所有的类上实现
IDisposable
,尤其是围绕 PerformanceCounter
的类。我写了更明确的清理我的
IList<PerformanceMonitor>
和内部结构,瞧,内存行为发生了变化。
它会振荡,但在很长一段时间内,内存使用量显然在可接受的范围内。
关于memory-leaks - 如何解决 System.Diagnostics.PerformanceCounter 导致的内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3266777/