-2

Well, I am trying to fetch memory (Private working set) for all running instance of Notepad . for example lets say 4 Process of Notepad is running, and now I want total memory consumed by all 4 instance of Notepad.

Till now I have tried for single to get memory (Private working set) for single

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;

I dont know why PerformanceCounter doesn't works with PID. on each iteration it is able to detect Notepad pid for different instance, but at end same Working Set value for all instance.

Please help me . Thanx in advance

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Vivek Sharma
  • 29
  • 2
  • 12
  • Surely you want more of that code inside your foreach loop of the processes found? which is why you get the same value rather than all values – BugFinder Aug 19 '15 at 07:49
  • Even after geting the PID, at the end we have to pass Instance name, i.e again Notepad. So Now again I am back to pavilion :'( – Vivek Sharma Aug 19 '15 at 07:51
  • Yes, but, your loops sets idnum1 to be the id, but you'll only ever end up with idnum1 being the value of the last in the loop.... so it only gets the memory usage of the last item. but then you dont use idnum1 either. – BugFinder Aug 19 '15 at 07:56
  • OK, seems there is some confusion, the code I have posted is partial, I just want is it possible to get memory (Private working set) using pid, because I don't know whether PerformanceCounter really accept pid or or not, I tries several time to search Notepad memory using pid, but getting exception, PerformanceCounter PC = new PerformanceCounter( "Process", "Working Set - Private", InstanceName); Now tell me is it possible to find Working set using PID, if Yes please tell me how ? – Vivek Sharma Aug 19 '15 at 08:01
  • you didnt mention that ...... its hard to help you then when the code you post isnt whats actually running. – BugFinder Aug 19 '15 at 08:02
  • is it possible to find "Working set" (memory usage) using PID for single process with "N" instance, if Yes please tell me how ? – Vivek Sharma Aug 19 '15 at 09:04

4 Answers4

1

I know it has been answered before here, but just for the sake of complete working code I'm posting this solution. Please note this code based on the method submitted by M4N in the link chain:

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 ");
}

Also, if you want to get the total memory of multiple instances of the same process use the above methods with the following one:

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;
}
Community
  • 1
  • 1
0

Finally I got the output, If there are multiple instance of same process.. like Notepad has 4 instance, then it will be consider as Notepad Notepad#1 Notepad#2 Notepad#3

well, I am posting my code, people are requested to debug there own and comment it before I close it.

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;
            }
        }
    }
Vivek Sharma
  • 29
  • 2
  • 12
  • You already got the processes in your call to `Process.GetProcessesByName()`.. there is no need to again get the process via `Process.GetProcessById()`. – Sam Axe Aug 19 '15 at 19:47
  • Additionally, the use of a `PerformanceCounter` is unwarranted given the `Process` class defines a `WorkingSet` property, as well as `WorkingSet64`. – Sam Axe Aug 19 '15 at 19:48
0

Ok So, Here is the optimized code, This is to check "Working Set - Private" for a process running N instance. like suppose 4 instance of Notepad is running, then it will be consider as Notepad Notepad#1 Notepad#2 Notepad#3

NOTE: InstanceName name is without extension , you can verify it by your Task Manager. "Working Set - Private" will be use while coding, but for verifying you can check with column Memory (Private Working Set ) under Processes tab in Task Manager

 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;
            }
            }
        }
Vivek Sharma
  • 29
  • 2
  • 12
-1

The code you posted is just painful. Try this:

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;
}

Or if you like LINQ:

var memory = (from p in Process.GetProcessesByName("notepad.exe") select p.WorkingSet).Sum();
Sam Axe
  • 33,313
  • 9
  • 55
  • 89
  • 'System.Diagnostics.Process.WorkingSet' is obsolete: '"This property has been deprecated. Please use System.Diagnostics.Process.WorkingSet64 instead. http://go.microsoft.com/fwlink/?linkid=14202"' – Vivek Sharma Aug 19 '15 at 20:10
  • `1.` Posting compiler warnings with no explanation doesn't do anyone any good. `2.` PeakWorkingSet and WorkingSet are two entirely different things. – Sam Axe Aug 19 '15 at 20:14
  • well, I am looking for "Working Set - Private", – Vivek Sharma Aug 19 '15 at 20:14
  • Somebody please edit my Question to, how to find ("Working Set - Private") for all running instance of same process, like find "Working Set - Private" for all instance of Notepad – Vivek Sharma Aug 19 '15 at 20:33