Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get CPU and RAM usage

I need to get the ram memory and CPU usage during execution of a process (the process can run sometimes and over 30 minutes). I am able to get the free RAM but the CPU usage it's not correct, compared with the value from task manager. Am I doing something wrong? Here is my code:

class Program
{
    static List<float> AvailableCPU = new List<float>();
    static List<float> AvailableRAM = new List<float>();

    protected static PerformanceCounter cpuCounter;
    protected static PerformanceCounter ramCounter;
    static void Main(string[] args)
    {
        cpuCounter = new PerformanceCounter();
        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";

        ramCounter = new PerformanceCounter("Memory", "Available MBytes");

        try
        {
            System.Timers.Timer t = new System.Timers.Timer(1200);
            t.Elapsed += new ElapsedEventHandler(TimerElapsed);
            t.Start();
            Thread.Sleep(10000);
        }
        catch (Exception e)
        {
            Console.WriteLine("catched exception");
        }
        Console.ReadLine();

    }

    public static void TimerElapsed(object source, ElapsedEventArgs e)
    {
        float cpu = cpuCounter.NextValue();
        float ram = ramCounter.NextValue();
        Console.WriteLine(string.Format("CPU Value: {0}, ram value: {1}", cpu, ram));
        AvailableCPU.Add(cpu);
        AvailableRAM.Add(ram);
    }

}

But when I run the program, here is what it's printed to the console, compared with values from task manager: cpu usage

What am I doing wrong?

like image 330
Buda Gavril Avatar asked Oct 28 '15 09:10

Buda Gavril


2 Answers

There is nothing wrong with your values.

The reason you see differences with what task manager returns is that the "CPU usage" value is something computed for a given interval, i.e. between two NextValue() calls. If task manager "doesn't call its own NextValue" (if we simplify how it works) at the same time you do, you won't return the same results.

Imagine the following scenario:

Time 0: 0% actual CPU usage
Time 1: 50% actual CPU usage
Time 2: 70% actual CPU usage
Time 3: 2% actual CPU usage
Time 4: 100% actual CPU usage
  • If you check the value between Time 1 and Time 3, you'll return something based on "50% and 2%".
  • If task manager checks the value between Time 2 and Time 4, it'll return something different, i.e. a value based on "70% and 100%".

You could try to spawn multiple processes of your own application, you should also see different results.

like image 174
ken2k Avatar answered Oct 08 '22 12:10

ken2k


Here is what I've found: I've created a list with PerformanceCounter objects for each core, I add the percent and divide the result at number of phisical cores:

    class Program
    {
        static List<float> AvailableCPU = new List<float>();
        static List<float> AvailableRAM = new List<float>();

        protected static PerformanceCounter cpuCounter;
        protected static PerformanceCounter ramCounter;
        static List<PerformanceCounter> cpuCounters = new List<PerformanceCounter>();
        static int cores = 0;
        static void Main(string[] args)
        {
            cpuCounter = new PerformanceCounter();
            cpuCounter.CategoryName = "Processor";
            cpuCounter.CounterName = "% Processor Time";
            cpuCounter.InstanceName = "_Total";

            foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
            {
                cores = cores + int.Parse(item["NumberOfCores"].ToString());
            }

            ramCounter = new PerformanceCounter("Memory", "Available MBytes");

            int procCount = System.Environment.ProcessorCount;
            for(int i = 0; i < procCount; i++)
            {
                System.Diagnostics.PerformanceCounter pc = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", i.ToString());
                cpuCounters.Add(pc);
            }

            Thread c = new Thread(ConsumeCPU);
            c.IsBackground = true;
            c.Start();

            try
            {
                System.Timers.Timer t = new System.Timers.Timer(1200);
                t.Elapsed += new ElapsedEventHandler(TimerElapsed);
                t.Start();
                Thread.Sleep(10000);
            }
            catch (Exception e)
            {
                Console.WriteLine("catched exception");
            }
            Console.ReadLine();

        }

        public static void ConsumeCPU()
        {
            int percentage = 60;
            if (percentage < 0 || percentage > 100)
                throw new ArgumentException("percentage");
            Stopwatch watch = new Stopwatch();
            watch.Start();
            while (true)
            {
                // Make the loop go on for "percentage" milliseconds then sleep the 
                // remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
                if (watch.ElapsedMilliseconds > percentage)
                {
                    Thread.Sleep(100 - percentage);
                    watch.Reset();
                    watch.Start();
                }
            }
        }

        public static void TimerElapsed(object source, ElapsedEventArgs e)
        {
            float cpu = cpuCounter.NextValue();
            float sum = 0;
            foreach(PerformanceCounter c in cpuCounters)
            {
                sum = sum + c.NextValue();
            }
            sum = sum / (cores);
            float ram = ramCounter.NextValue();
            Console.WriteLine(string.Format("CPU Value 1: {0}, cpu value 2: {1} ,ram value: {2}", sum, cpu, ram));
            AvailableCPU.Add(sum);
            AvailableRAM.Add(ram);
        }

    }

Here is the screenshot with the results (as you can see, the first method is more precise):

enter image description here

like image 23
Buda Gavril Avatar answered Oct 08 '22 11:10

Buda Gavril