我想使用.NET / Process性能计数器在网页上显示一些内存统计信息(工作集,GC等)。不幸的是,如果该服务器上有多个应用程序池,则使用索引(#1,#2等)对它们进行区分,但我不知道如何将进程ID(我有)与该#xx索引进行匹配。是否有编程方式(来自ASP.NET网页)?
答案 0 :(得分:11)
谷歌首次曝光:
Multiple CLR performance counters appear that have names that resemble "W3wp#1"
当多个ASP.NET工作进程时 正在运行,公共语言运行时 (CLR)性能计数器将有 名称类似于“W3wp#1”或 “W3sp#2”等。这是补救措施 在.NET Framework 2.0中包含一个 计数器名为.NET中的进程ID CLR内存性能对象。这个 counter显示的进程ID 实例。你可以使用这个计数器 确定CLR性能计数器 与流程相关联。
另外KB 281884:
默认情况下,性能监视器 (Perfmon.msc)显示多个 具有相同名称的进程 枚举中的过程 以下方式:
流程#1流程#2流程#3
性能监视器也可以显示 通过追加这些过程 进程ID(PID)到的名称 以下方式:
Process_PID
答案 1 :(得分:11)
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 ...");
}
答案 2 :(得分:1)
chiru的示例在特定情况下不起作用 - 如果您有相同程序的两个版本,名称相同,而另一个不是.net,则在非.NET版本之后启动.net版本。 .Net版本将命名为应用程序#1,但是当您使用此名称访问CLR perf计数器时,计数器上的实例名称的名称不是#1,因此您将失败。
尼克。
答案 3 :(得分:1)
即使更改注册表设置看起来很容易,但遗憾的是我们大多数人都没有权利在服务器上执行此操作(或者我们不想触摸它!)。在这种情况下,有一个小的解决方法。我在博客上写了here。
答案 4 :(得分:0)
我知道它之前已经得到了解答,但仅仅是为了完整的工作代码,我发布了这个解决方案。请注意此代码基于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;
}