はじめに
現在動作しているプログラムのメモリ情報やCPU使用率など、通常はパフォーマンスモニタで確認する情報を、常時取得できるようにするプログラムを作りたくて調査しました。
短期的にはパフォーマンスモニタを起動しておけばよいのですが、産業機器では一年中電源を入れっぱなしのことも多いので、長期間のデータを確認したいことが多いのです。プログラム中に仕込んでしまえばよいのですが、そのようなことをあまり意識して設計されていないソフトウェアでは修正が大変になってしまいますので、その辺も含めて検討しました。
メモリリークを確認したい
現在動作しているプログラムで、プログラムのコードを修正することなく、メモリリークやCUP使用率を確認したり、その情報をLogとして残したりしたいときがあります。特に、長期的に確認したい場合などはデータも大量になりますので、自分なりのフォーマットでLogに残したいことが多くあります。
.NETのSystem.Diagnostics.PerformanceCounter クラスを使うとパフォーマンスモニタで確認できるデータを外部プロセスから確認できます。
カテゴリとカウンタ
PerformanceCounterで取得できる情報について調査したのですが、まとまった情報が見つかりませんでしたので、パフォーマンスモニタの設定を参照しています。
パフォーマンスモニタでカテゴリとカウンタを調べる
今回は外部のMS Edgeの使用メモリを設定してみようとおもいます。
- パフォーマンスモニタを起動します。
パフォーマンスモニタの起動方法は幾つもありますが、私は[Windows]マークを右クリックして「コンピュータの管理」から「パフォーマンス」を選択して「パフォーマンス」「モニタツール」からパフォーマンスモニタを開くことが多いです。
- カテゴリを調べる
カウンタの追加 [Ctrl] + [A]で「カウンタの追加」ダイアログを開きます。カテゴリ一覧が表示されます。今回は外部プロセスなので「Process」を選択しました。
- カウンタを調べる
Processの横の^をクリックするとカウンタが展開されます。今回はWorking Setを選択しました。
- インスタンスを調べる
「選択したオブジェクトのインスタンス」のリストから現在動作中のインスタンス一覧が表示されます。今回はEdgeのインスタンス「msedge」を選択しました。
ここで調査したデータを使ってC#でプログラムを組んでみます。
カテゴリ : Process
カウンタ : Working Set
インスタンス: msedge
サンプルプログラム
ここでは、.NET6 コンソールアプリで1s間隔でメモリを表示するだけの簡単な例を載せておきます。
using System.Diagnostics;
PerformanceCounter pc = new PerformanceCounter();
pc.CategoryName = "Process"; // "Memory";
pc.CounterName = "Working Set"; // "Available MBytes";
pc.InstanceName = "msedge"; // ""
// カテゴリが存在するか確かめる
if(!System.Diagnostics.PerformanceCounterCategory.Exists(pc.CategoryName))
{
Console.WriteLine("登録されていないカテゴリです!");
return;
}
// カウンタが存在するか確かめる
if(!PerformanceCounterCategory.CounterExists(pc.CounterName,pc.CategoryName, "."))
{
Console.WriteLine("登録されていないカウンタです!");
return;
}
do
{
float m = pc.NextValue();
Console.WriteLine("{0}", m);
Thread.Sleep(1000);
} while (true);