【问题标题】:how to find memory (Private working set) for all running instance only of Notepad如何仅为记事本的所有运行实例查找内存(私有工作集)
【发布时间】:2015-08-19 07:46:59
【问题描述】:

好吧,我正在尝试为所有正在运行的 Notepad 实例获取内存(私有工作集)。 例如,假设 4 个记事本进程正在运行,现在我想要所有 4 个记事本实例消耗的总内存。

到目前为止,我已经尝试过为单人获取内存(私人工作集)

Process[] proc = Process.GetProcessesByName(Notepad);
foreach (var kl in proc)
{
   idnuml = kl.Id; // fetching pid for Notepad running instance.
}
PerformanceCounter PC = new PerformanceCounter( "Process", "Working Set -  Private", InstanceName);
memsize = Convert.ToInt32(PC.NextValue()) / 1024;

我不知道为什么 PerformanceCounter 不适用于 PID。 在每次迭代中,它能够检测不同实例的记事本 pid,但最终所有实例的工作集值相同。

请帮帮我。 提前感谢

【问题讨论】:

  • 您确定要在找到的进程的 foreach 循环中添加更多代码吗?这就是为什么你得到相同的值而不是所有的值
  • 即使在获得 PID 之后,最后我们也必须传递实例名称,即再次记事本。所以现在我又回到了展馆:'(
  • 是的,但是,您的循环将 idnum1 设置为 id,但您最终只会将 idnum1 设置为循环中最后一个的值......所以它只会获取内存最后一项的用法。但是你也不使用 idnum1。
  • 好的,似乎有些混乱,我发布的代码是部分的,我只想使用pid获取内存(私有工作集),因为我不知道PerformanceCounter是否真的是否接受pid,我尝试了几次使用pid搜索记事本内存,但出现异常,PerformanceCounter PC = new PerformanceCounter("Process", "Working Set - Private", InstanceName);现在告诉我是否可以使用 PID 找到工作集,如果是,请告诉我如何?
  • 你没有提到......当你发布的代码不是实际运行的时候,它很难帮助你。

标签: c# performancecounter


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    最后我得到了输出, 如果同一进程有多个实例.. 像记事本有 4 个实例,那么它将被视为 记事本 记事本#1 记事本#2 记事本#3

    好吧,我正在发布我的代码,请人们在我关闭它之前自己调试并评论它。

    public int m_PMmonitor()
        {
    
            int count = 0,sum=0;
            int[] lm = new int[10];
            while (true)
            {
    
                try
                {
                    Process[] proc = Process.GetProcessesByName(InstanceName);
                    PerformanceCounter PC;
                    sum = proc.Count();
                    int k = 0;
                    string pname;
                    foreach (var pro in proc)
                    {
    
                        lm[count] = pro.Id;
                        if ((sum-1) == count)
                        {
                            for (int i = 0; i <= (sum - 1); i++)
                            {
                                Process p = Process.GetProcessById(lm[i]);
                                pname = p.ProcessName;
                                if (k == 0)
                                {
                                    PC = new PerformanceCounter("Process", "Working Set - Private", pname, true);
                                    memsize = Convert.ToInt32(PC.NextValue()) / 1024;
                                    Console.WriteLine(memsize);
                                    k++;
                                }
                                else
                                {
                                    PC = new PerformanceCounter("Process", "Working Set - Private", pname + "#" + (k).ToString(), true);
                                    memsize = Convert.ToInt32(PC.NextValue()) / 1024;
                                    Console.WriteLine(memsize);
                                    k++;
                                }
                                memsize = Convert.ToInt32(PC.NextValue()) / 1024;
                            }
                        }
                        count++;
                    }
                    Thread.Sleep(800);
                    return memsize ;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
    
                    Thread.Sleep(800);
                    return 0;
                }
            }
        }
    

    【讨论】:

    • 您已经在对Process.GetProcessesByName()的调用中获得了进程。无需再次通过Process.GetProcessById()获得进程。
    • 此外,鉴于Process 类定义了WorkingSet 属性以及WorkingSet64,因此使用PerformanceCounter 是没有根据的。
    【解决方案3】:

    好的,这是优化后的代码, 这是为了检查运行 N 实例的进程的“工作集 - 私有”。 比如假设 4 个记事本实例正在运行,那么它将被视为 记事本 记事本#1 记事本#2 记事本#3

    注意:InstanceName 名称没有 extension ,您可以通过任务管理器对其进行验证。 "Working Set - Private" 将在编码时使用, 但要进行验证,您可以检查任务管理器中进程选项卡下的列内存(私有工作集)

     public int m_PMmonitor()
        {
    
            int count = 0, sum = 0,buff=0;
            while (true)
            {
    
                try
                {
                    Process[] proc = Process.GetProcessesByName(InstanceName);
                    PerformanceCounter PC;
                    sum = proc.Count();
                    int k = 0;
                    foreach (var pro in proc)
                    {
                                if (k == 0)
                                {
                                    PC = new PerformanceCounter("Process", "Working Set - Private", InstanceName, true);
                                }
                                else
                                {
                                    PC = new PerformanceCounter("Process", "Working Set - Private", InstanceName + "#" + (k).ToString(), true);
                                }
                                memsize = Convert.ToInt32(PC.NextValue()) / 1024;
                                Console.WriteLine(memsize);
                                buff = buff + memsize; //adding memsize of current running instance
                                PC.Dispose();
                                PC.Close();
                                count++;
                                k++;
                    }
                    Thread.Sleep(800);
                    return buff;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
    
                    Thread.Sleep(800);
                    return 0;
                }
                }
            }
    

    【讨论】:

      【解决方案4】:

      您发布的代码只是痛苦。试试这个:

      public int m_PMmonitor() {
          var processes = Process.GetProcessByName("notepad.exe");
          int memory = 0;
      
          foreach (var process in processes) {
              memory += process.WorkingSet / (1024^2);  // convert bytes to MB
          }
      return memory;
      }
      

      或者如果你喜欢 LINQ:

      var memory = (from p in Process.GetProcessesByName("notepad.exe") select p.WorkingSet).Sum();
      

      【讨论】:

      • 'System.Diagnostics.Process.WorkingSet' 已过时:'"此属性已被弃用。请改用 System.Diagnostics.Process.WorkingSet64。go.microsoft.com/fwlink/?linkid=14202"'
      • 1. 在没有解释的情况下发布编译器警告对任何人都没有任何好处。 2. PeakWorkingSet 和 WorkingSet 是两个完全不同的东西。
      • 好吧,我正在寻找“Working Set - Private”,
      • 有人请将我的问题编辑为,如何为同一进程的所有正在运行的实例查找(“工作集 - 私有”),例如为记事本的所有实例查找“工作集 - 私有”
      猜你喜欢
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 2022-01-22
      相关资源
      最近更新 更多