Using OperatingSystemMXBean to get CPU usage
Asked Answered
U

1

23

I'm trying to use Java to get the percentage of CPU used by the currently running Java Virtual Machine. My research has pointed me to using the com.sun.management.OperatingSystemMXBean class. Following examples online, I've written the following:

import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;


public class TestClass {

public static void main (String[] args) {
    OperatingSystemMXBean bean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();

    System.out.println(bean.getProcessCpuLoad());
    System.out.println(bean.getSystemCpuLoad());

    }

}

After testing this on two machines, I can't stop getting a result of -1.0 for both calls. I have tried running this code using both 64- and 32-bit versions of Java 7 and 6 through various methods. Still, all I get is a print out of -1.0 which, according to the Javadocs,

All values betweens 0.0 and 1.0 are possible depending of the activities going on in the system. If the system recent cpu usage is not available, the method returns a negative value.

I don't know what else to do here. Getting the CPU load is critical, and I'd like to avoid using another library like Sigar. Anybody have any recommendations or have any insights into this problem?

Untrimmed answered 5/11, 2013 at 2:45 Comment(0)
U
44

Just answering my own question in case it could help somebody.

What I was doing was technically correct, however I was not giving the OperatingSystemMXBean enough time to gather CPU usage information. The JVM must actually be running for a few seconds before it can gather CPU usage information, and then the refresh resolution is implementation-dependent it would seem.

Running the code with the following change will start to produce usage information after ~2 seconds on my machine:

public static void main(String[] args) {
    OperatingSystemMXBean bean = (com.sun.management.OperatingSystemMXBean) ManagementFactory
            .getOperatingSystemMXBean();

    while (true) {
        System.out.println(bean.getProcessCpuLoad());
        System.out.println(bean.getSystemCpuLoad());
    }

}

Hopefully this can help somebody

Untrimmed answered 8/12, 2013 at 18:21 Comment(5)
Thanks for this answer but i have observed that running this code increases CPU utilization by 30-40%. This means that we get increased CPU Utilization whenever we run this codeTwoup
@Shashank This code was only meant to demonstrate the lag in getting CPU usage information. In a real system, you shouldn't make this call in an infinite loop. Just once per use case is enough after a few moments of the application running.Untrimmed
Even running this code for 1-2 sec increases the CPU usage.Twoup
You made my day @shashank :)Selena
Fully-working example, in case anyone is interested: github.com/luciopaiva/java-simple-system-infoFigurate

© 2022 - 2024 — McMap. All rights reserved.