【问题标题】:Get Performance Counter Instance Name (w3wp#XX) from ASP.NET worker process ID从 ASP.NET 工作进程 ID 获取性能计数器实例名称 (w3wp#XX)
【发布时间】:2010-09-11 22:50:51
【问题描述】:

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

【问题讨论】:

  • 这里有一篇博文详细讨论了这种情况:weblog.west-wind.com/posts/2014/Sep/27/…。基本上,您需要使用另一个性能计数器来检索“实例名称”,然后使用该名称运行您的进程计数器。

标签: asp.net iis-6 performancecounter


【解决方案1】:
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 ...");
}

【讨论】:

  • 我认为它更快: Process p = Process.tGetProcessById(pid);字符串实例 = Process.ProcessName;
  • @pistacchio 不,如果有多个进程实例,这会给您错误的值。
【解决方案2】:

Google 上的第一次点击:

Multiple CLR performance counters appear that have names that resemble "W3wp#1"

当多个 ASP.NET 工作进程 正在运行,公共语言运行时 (CLR) 性能计数器将具有 类似于“W3wp#1”的名称或 “W3sp#2”等等。这已得到补救 在 .NET Framework 2.0 中包含一个 .NET 中名为 Process ID 的计数器 CLR 内存性能对象。这 计数器显示进程 ID 实例。您可以使用此计数器 确定 CLR 性能计数器 与进程相关联。

还有KB 281884:

默认情况下,性能监视器 (Perfmon.msc) 显示多个 具有相同名称的进程 枚举进程中的 以下方式:

进程#1 进程#2 进程#3

性能监视器还可以显示 这些过程通过附加 进程 ID (PID) 中的名称 以下方式:

进程_PID

【讨论】:

  • 其实这样是不对的——看起来命名是Process,Process#1,Process#2。里面有一个没有后缀的。
【解决方案3】:

尽管更改注册表设置看起来很容易,但不幸的是,我们大多数人都无权在服务器上进行更改(或者我们不想碰它!)。在这种情况下,有一个小的解决方法。我在博客上写过这个here

【讨论】:

    【解决方案4】:

    chiru 的示例在特定情况下不起作用 - 当您有同一个程序的两个版本,名称相同,一个不是 .net 并且您在非 .net 版本之后启动 .net 版本。 .Net 版本将被命名为 applicaion#1,但是当您使用此名称访问 CLR 性能计数器时,计数器上的实例名称的名称没有 #1,因此您会失败。

    尼克。

    【讨论】:

      【解决方案5】:

      我知道之前已经回答过了,但只是为了完整的工作代码,我发布了这个解决方案。请注意此代码基于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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多