JakeSmitch
JakeSmitch

Reputation: 111

How can I get the CPU usage of a process with "tasklist" in Windows

I am writing a program in Java to periodically display the CPU and memory usage of a given process ID. My implementation invokes tasklist. It is pretty straightforward to get the memory usage by the following command:

tasklist /fi "memusage ge 0" /fi "pid eq 2076" /v

This will return the memory usage of process id 2076 and i can use this for my task. By invoking the following command, I can extract the CPU Time.

tasklist /fi "pid eq 2076" /fi "CPUTIME ge 00:00:00" /v

My question is, how would I go about getting the CPU usage of this process?

I found a post on StackOverflow for my question but the answer isn't clear and I don't understand what to type in the command to get what I need. The question was answered in 2008 and someone asked for clarification in 2013 but the person that answered the question hasn't replied.

Here is the post that I have found.

Upvotes: 11

Views: 27089

Answers (3)

JamesJJ
JamesJJ

Reputation: 954

Memory is like a tea cup, it maybe full or empty, an instantaneous look at the cup allows you to see how full of tea it is (that is your "memusage" command).

CPU is like a ski lift. It moves at a reasonably constant rate irrespective of whether your are riding the lift or not. It is not possible to determine your usage in a single instantaneous observation - we need to know how long you were riding it for (that is your "cputime" command). You have to use the "cputime" command at least twice!

For example:

  • At 7:09 pm, you run the cputime command on your process, and it returns "28 minutes"
  • At 7:17 pm, you run the cputime command on your process again, and it returns "32 minutes"

From the first time you ran the cputime command to the second time, the usage has increased from 28 minutes to 32 minutes -- the process has used 4 minutes of CPU time.

From 7:09pm to 7:17pm is a duration of 8 minutes -- A total of 8 minutes of time were available, but your process just used 4 minutes: 4 / 8 = 50% average system usage.

If your system has multiple processors, then you can divide by the total number of CPUs to get an average per CPU - e.g. 50% / 2 = 25% average in a dual cpu system.

I used minutes above for ease of writing - in reality you may be looking at how many nanoseconds of CPU time the process used during a time window that is just milliseconds long.

Upvotes: 6

Pwnstar
Pwnstar

Reputation: 2245

I once wrote a class:

private static class PerformanceMonitor {
    private int availableProcessors = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
    private long lastSystemTime = 0;
    private long lastProcessCpuTime = 0;

    /**
     * Get's the cpu usage of the jvm
     *
     * @return the cpu usage a double of percentage
     */
    private synchronized double getCpuUsage() {
        if (lastSystemTime == 0) {
            baselineCounters();
            return 0d;
        }

        long systemTime = System.nanoTime();
        long processCpuTime = 0;

        if (getOperatingSystemMXBean() instanceof com.sun.management.OperatingSystemMXBean) {
            processCpuTime = ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getProcessCpuTime();
        }

        double cpuUsage = ((double) (processCpuTime - lastProcessCpuTime)) / ((double) (systemTime - lastSystemTime));

        lastSystemTime = systemTime;
        lastProcessCpuTime = processCpuTime;

        return cpuUsage / availableProcessors;
    }

    private void baselineCounters() {
        lastSystemTime = System.nanoTime();

        if (getOperatingSystemMXBean() instanceof com.sun.management.OperatingSystemMXBean) {
            lastProcessCpuTime = ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getProcessCpuTime();
        }
    }
}

Which is used like:

 private static final PerformanceMonitor _MONITOR = new PerformanceMonitor();
 _MONITOR.getCpuUsage();

This prints out the usage of the cpu consumed by the process of this JVM.

Upvotes: 0

craigts
craigts

Reputation: 3077

tasklist does not provide the information you are looking for. I would suggest using Get-Counter. A comment on an answer from the SuperUser site looks to be on track for what you're after.

Get-Counter '\Process(*)\% Processor Time' | Select-Object -ExpandProperty countersamples| Select-Object -Property instancename, cookedvalue| ? {$_.instanceName -notmatch "^(idle|_total|system)$"} | Sort-Object -Property cookedvalue -Descending| Select-Object -First 25| ft InstanceName,@{L='CPU';E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}} -AutoSize

Upvotes: 8

Related Questions