69

How can I get the CPU and Memory usage of a particular process using the .NET PerformanceCounter class? And also what is the difference between

Processor\% Processor Time and Process\% Processor Time?

I am a bit confused between these two.

SharpC
  • 5,368
  • 3
  • 37
  • 36
Anindya Chatterjee
  • 5,369
  • 11
  • 54
  • 78
  • 3
    There is no one correct way to measure memory usage. Memory can be used in many different ways. For example do you count memory swapped to disk or memory that's just reserved/committed but not written to yet,... – CodesInChaos Jan 13 '11 at 14:41

2 Answers2

126

From this post:

To get the entire PC CPU and Memory usage:

using System.Diagnostics;

Then declare globally:

private PerformanceCounter theCPUCounter = 
   new PerformanceCounter("Processor", "% Processor Time", "_Total"); 

Then to get the CPU time, simply call the NextValue() method:

this.theCPUCounter.NextValue();

This will get you the CPU usage

As for memory usage, same thing applies I believe:

private PerformanceCounter theMemCounter = 
   new PerformanceCounter("Memory", "Available MBytes");

Then to get the memory usage, simply call the NextValue() method:

this.theMemCounter.NextValue();

For a specific process CPU and Memory usage:

private PerformanceCounter theCPUCounter = 
   new PerformanceCounter("Process", "% Processor Time",              
   Process.GetCurrentProcess().ProcessName);

where Process.GetCurrentProcess().ProcessName is the process name you wish to get the information about.

private PerformanceCounter theMemCounter = 
   new PerformanceCounter("Process", "Working Set",
   Process.GetCurrentProcess().ProcessName);

where Process.GetCurrentProcess().ProcessName is the process name you wish to get the information about.

Note that Working Set may not be sufficient in its own right to determine the process' memory footprint -- see What is private bytes, virtual bytes, working set?

To retrieve all Categories, see Walkthrough: Retrieving Categories and Counters

The difference between Processor\% Processor Time and Process\% Processor Time is Processor is from the PC itself and Process is per individual process. So the processor time of the processor would be usage on the PC. Processor time of a process would be the specified processes usage. For full description of category names: Performance Monitor Counters

An alternative to using the Performance Counter

Use System.Diagnostics.Process.TotalProcessorTime and System.Diagnostics.ProcessThread.TotalProcessorTime properties to calculate your processor usage as this article describes.

Community
  • 1
  • 1
SwDevMan81
  • 45,922
  • 20
  • 140
  • 177
  • 1
    But will it give the current process's CPU/Mem usage from which the function is called? – Anindya Chatterjee Jan 13 '11 at 12:42
  • Memory Usage is not Memory Available. How do I get the Megabytes used, not available? – Patrick Szalapski Sep 10 '14 at 04:24
  • 1
    If I create theCPUCounter as above I get an InvalidOPerationException: "Cannot load Counter Name data because an invalid index '' was read from the registry." – Ted Nov 04 '14 at 14:38
  • 3
    Thank you for the detailed answer! When calling `new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName);` I get a percentage. How should I interpret this percentage? Is this % of all cores on the machine? – Legend May 01 '15 at 17:18
  • 1
    Watch out for that `GetCurrentProcess().ProcessName`. If you have multiple instances of your process, this can create a counter for the wrong instance. The actual names are something like "myprocess#1", "myprocess#2" etc, and yes, this is a real mess; they should have accepted process IDs instead of names. – Roman Starkov Jun 13 '15 at 23:02
  • 8
    @Legend My cursory testing shows it's the sum of the processor usage across each processor. For 4 cores, `PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName)` can return up to `400` meaning that process is using 100% of each CPU. Why this isn't made clear *anywhere* is unfortunate, as is having to rely on a cursory test. This is the highest voted/answered question for "How do I get CPU usage of a process?" for c# and still no one mentions it. Various technet, msdn, and msdn blog posts have contradicting information just to make it more confusing. – Quantic Aug 19 '16 at 20:43
  • 1
    You should call .NextValue() twice, as described here: https://blogs.msdn.microsoft.com/bclteam/2006/06/02/how-to-read-performance-counters-ryan-byington/ – Loreno Sep 02 '16 at 07:13
  • Ran into a problem with this today; the performance counter gets it's counter names from a registry value. If this registry value becomes corrupt some how then the performance counter may fail. To fix it you can run `lodctr /r` on the culprit machine. – maddisoj Sep 28 '16 at 16:54
  • 4
    For anyone still landing here, I want to piggyback on what @Quantic was saying about the values of the counters. As detailed [here](https://social.technet.microsoft.com/wiki/contents/articles/12984.understanding-processor-processor-time-and-process-processor-time.aspx), the `Processor (% Processor Time)` counter will be out of 100 and will give the total usage across all processors/cores/etc in the computer. However, the `Processor (% Process Time)` is scaled by the number of logical processors. To get average usage across a computer, divide the result by `Environment.ProcessorCount` – wlyles Apr 16 '18 at 20:38
4

Pelo Hyper-V:

private PerformanceCounter theMemCounter = new PerformanceCounter(
    "Hyper-v Dynamic Memory VM",
    "Physical Memory",
    Process.GetCurrentProcess().ProcessName); 
BlackBear
  • 20,590
  • 9
  • 41
  • 75
Fernando
  • 41
  • 1