measure CPU usage of the JVM : java code
Asked Answered
I

7

14

Is there a way to measure CPU usage of the JVM (once a java application is started) cross platform (windows + unix + mac)? I have used Jconsole but what I need is a java code that does this, and not a tool through which I can monitor CPU utilization. I have tried out

ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage()

using JMX, but it doesn't help since what I need is the specific CPU usage by the JVM (say when I start a server), not the system load average.

Ineffable answered 6/5, 2011 at 6:18 Comment(0)
P
9

You should have a look at the ThreadMXBean.getThreadCPUTime() method from the Thread MBean.

Thread CPU time

A Java virtual machine implementation may support measuring the CPU time for the current thread, for any thread, or for no threads.

There is also the JTop sample application that's part of the JDK jdk\demo\management\JTop\src\JTop.java or here. Have a look at:

/**
 * Get the thread list with CPU consumption and the ThreadInfo for each thread
 * sorted by the CPU time.
 */
private List<Map.Entry<Long, ThreadInfo>> getThreadList()
Pierce answered 6/5, 2011 at 6:32 Comment(2)
hi, is there a way to get cpu usage (in percentage) for the JVM using the ThreadMXBean.getCurrentCPUTime() method mentioed please?Ineffable
You have to calculate the sum of the CPU times of all threads to get the total CPU time. I think the sum could be off a bit because you cannot query for all threads' CPU times atomically.Pierce
M
2

At any given instant, a thread is either running (100% of core) or not (0%). There is no in-between. What you need is a short-term series of snapshots of the thread's running state, and average it over those.

Madigan answered 6/5, 2011 at 16:8 Comment(1)
Can you detail out a bit more? Won't you have to account for threads that get blocked or are in timed_waiting state? I have seen timed_waiting threads taking up cpu cycles at times. My requirement is to trigger the jvm to take more thread dumps when the cpu usage crosses a threshold value, so that we could investigate the problem.Chaffinch
D
2

From here

    com.sun.management.OperatingSystemMXBean operatingSystemMXBean = 
         (com.sun.management.OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
    long prevUpTime = runtimeMXBean.getUptime();
    long prevProcessCpuTime = operatingSystemMXBean.getProcessCpuTime();
    double cpuUsage;
    try 
    {
        Thread.sleep(500);
    } 
    catch (Exception ignored) { }

    operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    long upTime = runtimeMXBean.getUptime();
    long processCpuTime = operatingSystemMXBean.getProcessCpuTime();
    long elapsedCpu = processCpuTime - prevProcessCpuTime;
    long elapsedTime = upTime - prevUpTime;

    cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * availableProcessors));
    System.out.println("Java CPU: " + cpuUsage);
Distinction answered 31/3, 2013 at 18:49 Comment(1)
I tried this but it doesn't seem to give an accurate value. Comparing it with what I see in jconsole, the calculation is 65% when the cpu usage is already 99% on jconsole. Any java alternatives?Chaffinch
S
1

Java itself not providing this feature. There are couple of opensource APIs available to measure CPU Usage.
I recommend Sigar API. Apart from CPU usage, you can get lot more other features like memory usage, System uptime etc.

Schoolgirl answered 6/5, 2011 at 6:23 Comment(2)
This is not correct since Java 1.5, when ThreadMXBean.getCurrentCPUTime() was introduced, see @thomas-jung's answer. But Sigar does have some interesting functionality.Marston
SIGAR cantake down your JVM also and crash everything. Even if it is intermittent, i don't think you can afford that in production .Sassan
D
1

Perhaps this or similar libraries could help you out.

Dulce answered 6/5, 2011 at 8:6 Comment(0)
F
1

You can try to use https://github.com/mvysny/webmon . You just add the webmon-analyzer jar to your project and you'll start the sampler and TCP/IP server. The sampler will poll JMX API and will keep the stats for awhile, you can then simply telnet localhost 5455 to get a text dump of those stats. Awesome for production. Disclaimer: I'm the author, and the project is old-ish.

Floater answered 21/1, 2020 at 9:46 Comment(0)
D
0

Programmatically querying for CPU usage is impossible using pure Java. There is simply no API for this. A suggested alternative might use Runtime.exec() to determine the JVM's process ID (PID), call an external, platform-specific command like ps, and parse its output for the PID of interest.

See this link

Dual answered 6/5, 2011 at 6:23 Comment(1)
This is not correct since Java 1.5, when ThreadMXBean.getCurrentCPUTime() was introduced, see @Thomas-jung's answer. Also, the linked article is from 2002.Marston

© 2022 - 2024 — McMap. All rights reserved.