4

概要

パラメータとして使用するプロセスモニタコマンドラインアプリケーションを作成しました。

  • プロセス名またはプロセスID
  • CPUしきい値のパーセント。

プログラムが行うことは、渡された名前またはpidを持つすべてのプロセスを監視し、それらのCPU使用率がしきい値%を超えると、それらを強制終了します。

私には2つのクラスがあります: ProcessMonitorProcessMonitorList

前者はラップアラウンドSystem.Diagnostics.PerformanceCounter
後者は前者IEnumarableのリストのような構造を可能にするものです。

問題

プログラム自体は正常に動作しますが、タスクマネージャーでメモリ使用量を見ると、1秒あたり約20kBの増分で増加します。注:プログラムは、CPUカウンターをPerformanceCounter1秒ごとにポーリングします。

このプログラムは、頻繁に使用されるサーバーで実行する必要があり、監視しているプロセスは多数あります。(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クラス内にあるメソッド内にリークが存在することを示しています。

私の質問:

  1. これは既知の問題ですか、どうすれば回避できますか?
  2. タスクマネージャーのメモリ使用量が増加しているという私の仮定は、実際にメモリリークが正しいことを意味しますか?
  3. 特定のプロセスの複数のインスタンスを監視し、特定のしきい値のCPU使用率を超えた場合にそれらをシャットダウンしてから、電子メールを送信するためのより良い方法はありますか?
4

1 に答える 1

7

だから私はそれを理解したと思います。リフレクターツール
を使用して、内部のコードを調べることができました。System.Diagnostics

NextValueメソッドが呼び出すようです

GC.SuppressFinalization();

これは、すべてのクラスを明示的に呼び出す必要があることを意味します(私が思うに、間違っている場合は修正してください)。Dispose()

だから、私がしたことはIDisposable、私のすべてのクラス、特にラップアラウンドしたクラスに実装することPerformanceCounterです。

私は自分のIList<PerformanceMonitor>、そして内部のより明確なクリーンアップを書きました、そしてボイラー、メモリの振る舞いが変わりました。

発振しますが、メモリ使用量は長期間にわたって許容範囲内に明確に制限されています。

于 2010-07-17T15:30:41.503 に答える