Windowsでは管理ツールにシステムのパフォーマンスを計測・収集するツールとしてパフォーマンスモニタ(perfmon.exe)が用意されていますが、.NET FrameworkのSystem.Diagnostics.PerformanceCounterクラスを使うことにより、CPU使用率やメモリの使用状況など、システムやプロセス・スレッドのパフォーマンス情報をコード上で収集することができるようになります。
注意:Windows 9x系では、PerformanceCounterを使ったデータの収集はサポートされていません。 また、Monoではカテゴリ・カウンタの種類やプラットフォームによってはサポートされていない、もしくは未実装のものがあるようです。 カテゴリ・カウンタがサポートされているか調べる方法についてはパフォーマンスカウンタのカテゴリで解説しています。
PerformanceCounterクラス
パフォーマンス情報の計測
まずはPerformanceCounterクラスを使った簡単な例として、CPU使用率の測定を行ってみます。 次の例では、1秒ごとにCPU使用率を取得し、表示しています。
実行すると上記のような結果が得られます。 システムモニタのグラフと合わせて確認すると、結果が比較しやすいと思います。
上記のコードを簡単に解説すると、まずPerformanceCounterのインスタンス作成のところで、コンストラクタに計測する値のカテゴリ名・カウンタ名・インスタンス名を指定しています。 具体的には追って説明しますが、この部分を変えることで様々な値を計測することができます。 この例では、カテゴリ名が"Processor"でプロセッサ(CPU)、カウンタ名が"% Processor Time"でプロセッサ時間(%)、インスタンス名が"_Total"で全CPUの合計時間を計測するPerformanceCounterを作成していることになります。
計測した値を取得するためのメソッドがNextValueです。 CPU使用率の場合は戻り値は0.0から100.0までの値となりますが、計測する値の種類によって異なります。 この例では0.0から1.0までの値にスケーリングしなおしてから表示しています。
なお、実行結果では一番はじめの計測値が0.00%となっているのは、NextValueメソッドが「現在の値と以前の値の差を計測間隔時間で割ったもの」を算出結果として返すためです。 そのため、最初の呼び出しでは計算に使うための値がないため、0が返されます。 NextValueメソッドの戻り値の意味はカウンタが計測する値の種類によって変わりますが、CounterTypeプロパティを参照することでカウンタの値の種類を知ることができます。
また、リファレンスによると、NextValueメソッドの呼び出しは1秒間隔で行うことが推奨されています。 これより短い間隔で更新した場合は、値が更新されない可能性があります。 最初のNextValueの呼び出しの際、環境によっては結果が得られるまでに時間がかかる場合もあるようです。
フォームデザイナでの配置
PerformanceCounterはフォームデザイナからフォーム上に配置できるコンポーネントになっています。 配置する場合は、ツールボックスの「コンポーネント」から「PerformanceCounter」を選択します。 なお、PerformanceCounterはGUIを持たないので、配置してもフォーム上には現れません。
次に、CategoryName、CounterName、InstanceName等のプロパティ値を指定します。 まず、CategoryNameの一覧からどれか一つ選択すると、そのカテゴリに含まれる計測値がCounterNameの一覧に表示されます。 この中から計測したい値を選択します。 さらに、必要に応じてInstanceNameも選択します。
あとは、NextValueメソッドを呼び出し、結果を表示するようにするなど、必要なコードを記述します。 呼び出し方は、すでに説明した例の場合と同様です。
カテゴリ・カウンタ名・インスタンス名
カテゴリ名・カウンタ名・インスタンス名にそれぞれ適切な値を指定することで、様々な値を計測することができるようになります。
CategoryName, CounterName, InstanceName
先の例ではコンストラクタでカテゴリ名等を指定していますが、指定した値はプロパティで参照でき、また設定をすることもできます。 それぞれ対応するプロパティはCategoryName、CounterName、InstanceNameで、次の例のようにコンストラクタに何も指定せずインスタンスを作成し、後からカテゴリ等のプロパティを個別に設定することもできます。 次の例は、先のコードと同じ動作となります。
InstanceNameの例:CPUコア毎の使用率の取得
インスタンス名(InstanceName)は、カテゴリ・カウンタの種類は同じでも、特定の対象を指定して値を計測したい場合に指定します。 例えば、マルチコアCPUを使用している環境の場合は、プロセッサそれぞれの使用率を取得することができます。 この場合、インスタンス名には"_Total"ではなくプロセッサのインデックス、つまり"0"や"1"などを指定することでプロセッサそれぞれの使用率を取得することができます。
次の例ではEnvironment.ProcessorCountを参照してプロセッサ数を取得し、それぞれのプロセッサ毎の使用率を計測するPerformanceCounterを作成して、値を計測しています。
CounterNameの例:ユーザモード・特権モードの使用率・アイドル率の取得
カウンタ名(CounterName)では、計測する値の種類を指定します。 例えばカテゴリがCPU情報("Processor")の場合は、ユーザモード・特権モードの使用率・アイドル率などを計測することができます。 次の例では、それぞれの使用率を取得するPerformanceCounterを作成し、値を計測しています。 また、100%からアイドル率を差し引くことで全体の使用率も求めています。
この例ではインスタンス名(InstanceName)に"_Total"を指定していますが、既に解説したとおり、"0"や"1"などを指定することでプロセッサ毎に計測することもできます。
CategoryNameの例・CPU以外のパフォーマンス情報の収集
カテゴリ名(CategoryName)を変えることで、CPU情報("Processor"カテゴリ)以外にも、様々なパフォーマンス情報の収集を行うことができます。 次の例では、システムの全プロセス数、使用可能なメモリ、ディスクからの秒間読み込みバイト数を計測・表示しています。
CPU使用率の場合では、NextValueメソッドからパーセント値が返されますが、この例のようにカウンタの種類に応じて返される値の単位が変わるため、表示する場合などは適宜対応する必要があります。 値の単位や種類についてはCounterTypeで解説します。
CategoryName, CounterName, InstanceNameに指定できる値
パフォーマンスカウンタで計測できる値は、プロセス数や空きメモリなどどの環境でも共通して計測できるもののほか、ドライブ毎のディスクIOなどマシンによって計測できる対象が変わるものがあります。 そのため、カテゴリ名・カウンタ名・インスタンス名に指定できる値は、環境によって変わってきます。
具体的にどの値が指定できるかどうかを調べるには、パフォーマンスモニタ(perfmon.exe)を使う他にも、コード上からはPerformanceCounterCategoryクラスのメンバを使うことができます。 詳しくはパフォーマンスカウンタのカテゴリで解説します。
計測値の種類 (CounterType)
カウンタが計測する値の種類を調べるには、CounterTypeプロパティを参照します。 このプロパティはPerformanceCounterType列挙体の値となっていて、計測される生データの種類とNextValueの戻り値の算出方法を表すものです。 このプロパティから、NextValueメソッドが現在の値と以前の値の差を元にした値を返すのか、NextValueメソッドを呼び出した時点の計測値が返されるのかなどを知ることができます。
PerformanceCounterTypeの代表的なものとして以下のようなものがあります。 なお、生データから計算される値が整数値となる場合でも、NextValueメソッドでは浮動小数点型に変換された値が返されます。
CounterTypeの値 | 計測値とNextValueの戻り値 |
---|---|
Timer100Ns Timer100NsInverse |
直前の呼び出し時との計測値の差を基に求めた、100%に対する割合。 パーセント値(0~100)。 |
CountPerTimeInterval32 CountPerTimeInterval64 RateOfCountsPerSecond32 RateOfCountsPerSecond64 |
直前の呼び出し時との計測値の差を基に求めた、単位時間あたりの量。 実数値。 |
CounterDelta32 CounterDelta64 |
直前の呼び出し時との計測値の差。 整数値または実数値。 |
NumberOfItems32 NumberOfItems64 NumberOfItemsHEX32 NumberOfItemsHEX64 |
呼び出しを行った時点での計測値。 整数値。 |
次の例では、いくつかのカウンタを作成し、それぞれのCounterTypeを表示しています。
計測値の説明 (CounterHelp)
CounterHelpプロパティを参照すると、パフォーマンスカウンタの計測値についての説明を取得することができます。
次の例では、先の例で使用したカウンタのCounterHelpプロパティを参照し、説明を表示しています。