概要
パラメータとして使用するプロセスモニタコマンドラインアプリケーションを作成しました。
- プロセス名またはプロセスID
- CPUしきい値のパーセント。
プログラムが行うことは、渡された名前またはpidを持つすべてのプロセスを監視し、それらのCPU使用率がしきい値%を超えると、それらを強制終了します。
私には2つのクラスがあります:
ProcessMonitor
とProcessMonitorList
前者はラップアラウンドSystem.Diagnostics.PerformanceCounter
後者は前者IEnumarable
のリストのような構造を可能にするものです。
問題
プログラム自体は正常に動作しますが、タスクマネージャーでメモリ使用量を見ると、1秒あたり約20kBの増分で増加します。注:プログラムは、CPUカウンターをPerformanceCounter
1秒ごとにポーリングします。
このプログラムは、頻繁に使用されるサーバーで実行する必要があり、監視しているプロセスは多数あります。(20-30)。
これまでの調査
PerfMonを使用して、プロセスのプライベートバイトとすべてのヒープの合計バイト数を監視しました。以下で参照する記事に示されているロジックによると、結果は、変動している間、値が許容範囲内に制限されていることを示しています。したがって、メモリリークはありません:
記事
また、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使用率を超えた場合にそれらをシャットダウンしてから、電子メールを送信するためのより良い方法はありますか?