.NET/プロセス パフォーマンス カウンターを使用して、Web ページにいくつかのメモリ統計 (ワーキング セット、GC など) を表示したいと考えています。残念ながら、そのサーバーに複数のアプリケーション プールがある場合、それらはインデックス (#1、#2 など) を使用して区別されますが、(私が持っている) プロセス ID をその #xx インデックスに一致させる方法がわかりません。(ASP.NET Web ページから) プログラムによる方法はありますか?
5 に答える
private static string GetProcessInstanceName(int pid)
{
PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");
string[] instances = cat.GetInstanceNames();
foreach (string instance in instances)
{
using (PerformanceCounter cnt = new PerformanceCounter("Process",
"ID Process", instance, true))
{
int val = (int) cnt.RawValue;
if (val == pid)
{
return instance;
}
}
}
throw new Exception("Could not find performance counter " +
"instance name for current process. This is truly strange ...");
}
Google での最初のヒット:
「W3wp#1」に似た名前の複数の CLR パフォーマンス カウンターが表示される
複数の ASP.NET ワーカー プロセスが実行されている場合、共通言語ランタイム (CLR) パフォーマンス カウンターには、"W3wp#1" や "W3sp#2" などのような名前が付けられます。これは、.NET Framework 2.0 で修正され、.NET CLR メモリ パフォーマンス オブジェクトに Process ID という名前のカウンターが含まれるようになりました。このカウンターは、インスタンスのプロセス ID を表示します。このカウンターを使用して、プロセスに関連付けられている CLR パフォーマンス カウンターを特定できます。
また、KB 281884 :
既定では、パフォーマンス モニター (Perfmon.msc) は、次の方法でプロセスを列挙することにより、同じ名前を持つ複数のプロセスを表示します。
工程#1 工程#2 工程#3
パフォーマンス モニターは、次の方法で名前にプロセス ID (PID) を追加することで、これらのプロセスを表示することもできます。
プロセス_PID
レジストリ設定の変更は非常に簡単に見えますが、残念ながら、ほとんどの人はサーバー上でそれを行う権利を持っていません (または変更したくありません!)。その場合、小さな回避策があります。私はこれについてここにブログを書きました。
chiru による例は、特定のケースでは機能しません。同じ名前の同じプログラムの 2 つのバージョンがあり、1 つが .net ではなく、非 .net バージョンの後に .net バージョンを開始する場合です。.Net バージョンには applicaion#1 という名前が付けられますが、この名前を使用して CLR パフォーマンス カウンターにアクセスすると、カウンターのインスタンス名に #1 のない名前が付けられるため、エラーが発生します。
ニック。
以前に回答されたことは知っていますが、完全に機能するコードのために、このソリューションを投稿しています。このコードは、このチェーンで M4N によって提出されたメソッドに基づいていることに注意してください。
public static long GetProcessPrivateWorkingSet64Size(int process_id)
{
long process_size = 0;
Process process = Process.GetProcessById(process_id);
if (process == null) return process_size;
string instanceName = GetProcessInstanceName(process.Id);
var counter = new PerformanceCounter("Process", "Working Set - Private", instanceName, true);
process_size = Convert.ToInt32(counter.NextValue()) / 1024;
return process_size;
}
public static string GetProcessInstanceName(int process_id)
{
PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");
string[] instances = cat.GetInstanceNames();
foreach (string instance in instances)
{
using (PerformanceCounter cnt = new PerformanceCounter("Process", "ID Process", instance, true))
{
int val = (int)cnt.RawValue;
if (val == process_id)
return instance;
}
}
throw new Exception("Could not find performance counter ");
}
また、同じプロセスの複数のインスタンスの合計メモリを取得する場合は、上記のメソッドを次のメソッドと共に使用します。
public static long GetPrivateWorkingSetForAllProcesses(string ProcessName)
{
long totalMem = 0;
Process[] process = Process.GetProcessesByName(ProcessName);
foreach (Process proc in process)
{
long memsize = GetProcessPrivateWorkingSet64Size(proc.Id);
totalMem += memsize;
}
return totalMem;
}