はじめに
2004年11月号のdotnetマガジン連載「Visual Basic.NET タマヒヨ倶楽部」の記事で、Windowsの管理ツールの中にある「パフォーマンス」のような、CPUの負荷状況をリアルタイムに描画して表示するプログラムを作成しました。
記事では、CPUの占有率情報を取得し、アナログメーターのようなゲージを作成して表示するプログラムを作成してみましたが、今回はメモリの使用量をPerformanceCounter
クラスを使ってリアルタイムに把握し、フォームとコントロールで表示するプログラムを作成してみます。
対象読者
Visual Basic.NETを利用してプログラムを作成したことのある方を対象としています。
必要な環境
記事は、Visual Basic.NET2003、.Net Framework1.1で作成・動作確認を行っています。
PerformanceCounterクラスについて
「パフォーマンス」というツールは、コントロールパネルアプレットで提供されており、システムの状態を監視し結果をグラフなどで表示するプログラムです。メモリのページファイル、ディスクアクセスの状態、CPUの占有度を、時間の経過とともに折れ線グラフで表示することができます。
Visual Basic.NETでは、.NET Frameworkの中にある、「PerformanceCounter
」と呼ばれるクラスを使うことで、「パフォーマンス」が使用する情報を、独自のプログラムに組み込んで使うことができます。
パフォーマンスカウンタは、情報量がとても多いので、情報の種類ごとに「Category」と呼ばれる分類がなされ、「Category」内にさらに「Counter」「Instance」と階層構造で情報が分類されて格納されています。
.NET FrameworkクラスライブラリのPerformanceCounter
クラスは、コントロールパネルアプレットの「パフォーマンス」と同様、複数のカウンタを設定して、カウンタごとに違う情報を表示し、自作のプログラム内で使用することが可能になっています。
GUIの作成
ユーザーインターフェイスは、フォームとPanel
、Label
、Timer
コントロールで仕上げます。
- フォームに次のプロパティを設定します。今回は、プログラム実行時にフォームのサイズをユーザーによって変えられないようにしています。
FormBorderStyle
プロパティを「FixedDialog
」に設定すると、プログラム実行時フォームのサイズを変えることができなくなります。また、MaximumSizeBox
プロパティを「False
」にすると、フォームの右端に付く「最大化」ボタンを無効にできます。フォームの設定プロパティプロパティ 設定値 BackColor
Silver FormBorderStyle
FixedDialog Icon
MSGBOX03.ICO MaximumSizeBox
False Text
空きメモリ 「最大化」ボタンがグレー表示となり、プログラム実行時はこのボタンが使えないので、プログラムを最大化できない - インジケーターのマーカーは、
Panel
コントロールの中にLabel
コントロールを入れて、Label
コントロールのBackColor
プロパティを使って色を付けています。立体表示は、BorderStyle
プロパティを「Fixed3D」に設定します。Panel
コントロールは、「コンテナコントロール」と呼ばれる機能を持ったコントロールで、他のコントロールを自分の中に組み込むことができます。マーカーは、1つ作成したら、あとは必要な数をコピーすれば簡単です。必要な数を配置したら、Panel
内のLabel
コントロールのBackColor
プロパティで背景色を塗りつぶします。Panelコントロールの中にLabelコントロールをドラッグ & ドロップする - インジケーターの中央に配置するメーターは、
Label
コントロールを使用します。ProgressBar
コントロールを使ってもいいのですが、ProgressBar
コントロールだと途中でマークの色を変えることができません。今回は、残メモリ量によってマークの色を変えるようにしたいので、Label
コントロールとTextプロパティ、ForeColor
プロパティでメーターを表示するようにします。BorderStyle
プロパティを「Fixed3D」に設定し、Text
プロパティに「■」を17個入れ、Label
コントロールのサイズをこれに合わせるようにします。なお、Label
コントロールはオブジェクト名を「Labelmeter」に変更しています。 - できあがったら、フォームをコントロールのサイズに合わせ、
Timer
コントロールを配置します。Enabled
プロパティをプロパティウィンドウで「True」にしておきます。また、フォームの右端にある「閉じる」(×)ボタンは有効なので、このボタンでプログラムを終了するようにします。フォームのデザイン画面
プログラムについて
このプログラムは、次のような動作をします。
- フォーム起動時に、
PerformanceCounter
クラスからオブジェクトインスタンスを作成し、取得したいカテゴリ、カウンタ名を設定し、その情報を1度取得。 Timer
コントロールのTick
イベントプロシージャで、そのデータを使い、残メモリ量によって、マークの色を変えてLabelコントロールでメーターを表示。- メーターのマークは文字の「■」で、その都度残メモリ量に合わせて文字数を決定。
PerformanceCounterクラスとカウンタ情報の取得方法
PerformanceCounter
クラスを使ってメモリ情報を取得するには、どのカテゴリにあるのかを探さなければなりません。
方法としては、次の2つがあります。
- Windowsのコントロールパネルから「管理ツール-パフォーマンス」を選び、「カウンタの追加」ダイアログボックスでパフォーマンスオブジェクトとカウンタを探す。パフォーマンスオブジェクトが
PerformanceCounter
クラスのCategoryName
プロパティに、カウンタがCounterName
プロパティに対応している。 - Visual Basic.NETの「サーバエクスプローラ」からコンピュータ名を展開し、「パフォーマンスカウンタ」から探す。
今回は、利用可能な空きメモリを取得しますので、カテゴリ名は「memory」、カウンタ名は「Available MBytes」を選び、MB単位で空きメモリ量を取得します。
PerformanceCounterオブジェクトを作成し操作する方法
通常、コードでPerformanceCounter
クラスのインスタンスを作成する場合は、CategoryName
プロパティにカテゴリ名を、CounterName
プロパティに取得する値のあるカウンタ名を設定します。
MachineName
プロパティには、使用するコンピュータ名を設定しますが、ここにコンピュータ名を設定すると、そのコンピュータのパフォーマンスしか取得できなくなります。他のコンピュータでも動かすには、MachineName
プロパティに「.」を設定しておきます。
コンピュータ名は空白でも、カウンタの値を取得することができます。これであれば、コンピュータ固有の情報ではなく、どのコンピュータでも同じカテゴリのカウンタがあれば、その情報を取得することができます。そして、カウンタの値はNextValue
プロパティに格納されます。
- まず、変数を2つ宣言します。いずれも、複数のプロシージャから参照されることになるので、モジュールレベルで宣言します。
Dim MemCounter As New PerformanceCounter Dim pt As Single
MemCounter
は、これから情報を取得するPerformanceCounter
クラスのオブジェクトインスタンスへの参照を格納します。必ず、格納するオブジェクトと同じデータ型で宣言してください。また、宣言と同時にNew
キーワードを使ってオブジェクトを作成し、そこへの参照を代入しています。変数pt
は、カウンタの値をMB単位で値を取得するので小数点を格納できるように、Single
で宣言します。 - 次に、フォームの
Load
イベントプロシージャを作成します。ここで、パフォーマンスカウンタを作成し、値が取り出せる状態にしておきます。CategoryName
プロパティにカテゴリ名「memory」を、CounterName
プロパティに取得する値のあるカウンタ名「Available MBytes」を、MachineName
プロパティに「.」を設定します。いずれも、文字列で設定する点に注意してください。Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load MemCounter.CategoryName = "memory" MemCounter.CounterName = "Available MBytes" MemCounter.MachineName = "."
カウンタを作成したら、NextValue
プロパティから現在の値を取得し変数に格納しておきます。pt = MemCounter.NextValue End Sub
これで、カウンタ「Available MBytes」-利用可能な空きメモリ量をMB単位で取得できました。
カウンタの値を取得する
今度は、Timer
コントロールのTick
イベントプロシージャで、100ミリ秒ごとにカウンタの値を取り出し、Label
コントロールのメーターに表示します。
- プロシージャの冒頭で、
NextValue
プロパティからカウンタの値を取り出します。そして、フォームのText
プロパティに、「MB」という文字を付けて表示します。Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick pt = MemCounter.NextValue Me.Text = pt & "MB"
- Labelコントロールの文字色の設定を行います。
変数ptの値を調べ、75以上であれば文字色を緑(PaleGreen)に、75から51の間であれば黄色に、50から26の間であればオレンジに、25から0の間はマゼンタになるように、
Label
コントロールのForeColor
を設定します。なお、Case
節では、キーワードIs
で比較演算子による値評価、キーワードTo
で範囲による値評価となります。With Labelmeter Select Case pt Case Is > 75 .ForeColor = System.Drawing.Color.PaleGreen Case 51 To 75 .ForeColor = System.Drawing.Color.Yellow Case 26 To 50 .ForeColor = System.Drawing.Color.DarkOrange Case 0 To 25 .ForeColor = System.Drawing.Color.Magenta End Select
- 文字色が決まったら、今度は■の文字数を決めます。これは、メモリ量が5MBごとに1文字になるように、5で割って
Int
関数で整数部だけを取り出します。また、たとえば残メモリが1GB もあると、■が200文字にも達してしまいます。あまり多い量を表示しても意味がないので、19文字以上になる場合は最大で19文字まで表示するようにしておきます。Dim i, cnt As Byte Dim mark As String cnt = Int(pt / 5) If cnt >= 19 Then cnt = 19 End If
- 文字数が決まったら、一度現在の
Label
コントロールの表示を消してから、新たに■を表示するようにします。すなわち、Tick
イベントプロシージャが呼び出されるごとに、メーターの表示を更新するわけです。「■」の設定は、文字数をFor...Next
ステートメントに設定し、変数への代入を自動的に繰り返すようにします。表示する文字ができたら、Label
コントロールのText
プロパティに代入します。mark = "" For i = 1 To cnt mark = mark + "■" Next Labelmeter.Text = mark End With End Sub
これで、たとえば残メモリが20MBになればマゼンタで、52MB になれば黄色でメーターが表示されます。残メモリの表示
cnt = Int(pt / 5)
まとめ
今回は、.NET Frameworkクラスライブラリにある、PerformanceCounter
クラスで実装メモリの空き容量を把握するプログラムを作成しました。まとめると次のようになります。
PerformanceCounter
クラスを使って、メモリ情報やディスクの空き容量、CPU・プロセス占有率などの情報を取得することができる。- 空きメモリ量の情報を取得するには、
CategoryName
、CounterName
、MachineName
プロパティを使用して、PerformanceCounter
クラスのインスタンスを作成する。カウンタの値はNextValue
プロパティに格納される。
参考資料(リンク)
- MSDNライブラリ 『.NET Frameworkクラスライブラリ PerformanceCounterクラス』