15

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

4

5 回答 5

12
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 ...");
}
于 2009-01-29T09:34:24.650 回答
11

谷歌上的第一击:

出现多个 CLR 性能计数器,其名称类似于“W3wp#1”

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

还有知识库 281884

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

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

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

进程_PID

于 2008-09-22T09:26:59.880 回答
2

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

于 2009-10-23T01:59:55.550 回答
1

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

缺口。

于 2009-05-22T10:01:47.530 回答
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;
}
于 2016-11-14T20:54:04.237 回答