从ASP.NET辅助进程ID获取性能计数器实例名称(w3wp#XX)

时间:2008-09-22 09:10:09

标签: asp.net iis-6 performancecounter

我想使用.NET / Process性能计数器在网页上显示一些内存统计信息(工作集,GC等)。不幸的是,如果该服务器上有多个应用程序池,则使用索引(#1,#2等)对它们进行区分,但我不知道如何将进程ID(我有)与该#xx索引进行匹配。是否有编程方式(来自ASP.NET网页)?

5 个答案:

答案 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;
}
相关问题