6

I'm trying to get CPU utilization or usage using Java 11.

My expectation is the average percentage of total usage, I don't really have any interest in the number of cores or thread available on the CPU.

In simple term on 80% the CPU is very busy, and on 10% is more or less idling.

How do I get this?

I've been trying a couple of suggestions from stackoverflow.

Option 1. Using com.sun.management.OperatingSystemMXBean is not good, anything com.sun is old and should be avoided.

Option 2. There is a 3rd party org.hyperic.sigar.CpuInfo which seems to be old and no longer maintained project. The result of cpuInfo.getVendor(), cpuInfo.getModel() below is null null. That gives me confidence (sacarsm).

protected void getCPUUtilization4() {
        CpuInfo cpuInfo =  new CpuInfo();
        System.out.println(String.format("    CpuInfo: %s %s", cpuInfo.getVendor(), cpuInfo.getModel()));
    }

Option 3. Built-in inside Java java.lang.management.OperatingSystemMXBean. The problem with this option is the osBean.getSystemLoadAverage() is a double value. When my cpu is not busy ~ 1.3 , and when my CPU is busy reached up to ~2.9. The osBean.getAvailableProcessors() returns 8. I'm pretty sure it's an Intel Quad core with total of 8 threads. Doesn't matter, how do I make sense of these numbers?

protected double getCPUUtilization5() {
        OperatingSystemMXBean osBean =
            ManagementFactory.getOperatingSystemMXBean();
        if (startSystemAverage == null) {
            startSystemAverage = osBean.getSystemLoadAverage();
            peakSystemAverage = osBean.getSystemLoadAverage();
        }
        if (peakSystemAverage < osBean.getSystemLoadAverage()) {
            peakSystemAverage = osBean.getSystemLoadAverage();
        }
        
        double sysAvg = osBean.getSystemLoadAverage();
        logger.info("    getCPUUtilization5: "+ sysAvg + " num of processors: "+ osBean.getAvailableProcessors());
        return sysAvg;
        
    }

1 Answer 1

9

With the introduction of the module system, the type com.sun.management.OperatingSystemMXBean has become part of the official API, but for modular software, there must be a declared dependency to the module jdk.management rather than just java.management.

So you can officially use

double cpuLoad = ManagementFactory.getPlatformMXBean(
    com.sun.management.OperatingSystemMXBean.class).getCpuLoad();

but it’s also possible to access the JMX attribute dynamically, to avoid a strong code dependency:

try {
    double cpuLoad = (Double)ManagementFactory.getPlatformMBeanServer()
        .getAttribute(new ObjectName("java.lang:type=OperatingSystem"), "CpuLoad");
    …
} catch (JMException ex) {
    System.getLogger(CPULoad.class.getName()).log(System.Logger.Level.ERROR, "", ex);
}

Prior to JDK 14, use getSystemCpuLoad() or "SystemCpuLoad" instead of getCpuLoad() resp. "CpuLoad"

This will not force the availability of the extension, but use it when available.


The system load average is, simply said, the average number of processes competing for the CPU. So for a single CPU system, you can say, a value of more than one not only means that the CPU was entirely busy, but the runnable tasks would have used more CPU resources when they were available.

For n CPUs or cores, you could say a similar thing when the system load reached the value n, but mind that this is only an average. So with a load value of n there still could have been a peek load where more than n application competed for the CPU, followed by some under-utilization of the CPU cores. But with enough sample values or a sufficiently high sampling rate, you can say that a value of n or higher implies a CPU usage saturation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.