CPU Usage (%) MBean on Sun JVM

I modified a code from internet, like this, then I tested that and the result almost match the linux ps command's result.

/** below is the code */

public float getCpuUsed() {

    /** get a MXBean  */
    com.sun.management.OperatingSystemMXBean osMXBean =
    (com.sun.management.OperatingSystemMXBean) 
    ManagementFactory.getOperatingSystemMXBean();


    /** set old timestamp values */
    long previousJvmProcessCpuTime = osMXBean.getProcessCpuTime();


    int sleepTime = 350;
    /** sleep for a while to use to calculate */
    try {
        TimeUnit.MILLISECONDS.sleep(sleepTime);
    } catch (InterruptedException e) {
        logger.error("InterruptedException occurred while MemoryCollector sleeping...");
    }

    /** elapsed process time is in nanoseconds */
    long elapsedProcessCpuTime = osMXBean.getProcessCpuTime() - previousJvmProcessCpuTime;

    /** elapsed uptime is in milliseconds */

    long elapsedJvmUptime = sleepTime ;

    /** total jvm uptime on all the available processors */
    //long totalElapsedJvmUptime = elapsedJvmUptime * osMXBean.getAvailableProcessors() ;
    long totalElapsedJvmUptime = elapsedJvmUptime;
    //System.out.println("echo cpu processors num " + osMXBean.getAvailableProcessors());

    /** calculate cpu usage as a percentage value
       to convert nanoseconds to milliseconds divide it by 1000000 and to get a percentage multiply it by 100 */
    float cpuUsage = elapsedProcessCpuTime / (totalElapsedJvmUptime * 10000F);



    return (float)(Math.round(cpuUsage*10)/10);
}

Update: In Java 7 you can do it like so:

public static double getProcessCpuLoad() throws MalformedObjectNameException, ReflectionException, InstanceNotFoundException {

    MBeanServer mbs    = ManagementFactory.getPlatformMBeanServer();
    ObjectName name    = ObjectName.getInstance("java.lang:type=OperatingSystem");
    AttributeList list = mbs.getAttributes(name, new String[]{ "ProcessCpuLoad" });

    if (list.isEmpty())     return Double.NaN;

    Attribute att = (Attribute)list.get(0);
    Double value  = (Double)att.getValue();

    if (value == -1.0)      return Double.NaN;

    return ((int)(value * 1000) / 10.0);        // returns a percentage value with 1 decimal point precision
}

----- original answer below -----

In Java 7 you can use the hidden methods of com.sun.management.OperatingSystemMXBean:

getProcessCpuLoad()    // returns the CPU usage of the JVM

getSystemCpuLoad()     // returns the CPU usage of the whole system

Both values are returned as a double between 0.0 and 1.0 so simply multiply by 100 to get a percentage.

com.sun.management.OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
System.out.println(osBean.getProcessCpuLoad() * 100);
System.out.println(osBean.getSystemCpuLoad()  * 100);

Since these are hidden, undocumented, methods that exist in com.sun.management.OperatingSystemMXBean package and not in the java.lang.management.OperatingSystemMXBean there is a risk that they will not be available in some JVMs or in future updates, so you should decide if you're willing to take that risk or not.

see https://www.java.net/community-item/hidden-java-7-features-%E2%80%93-system-and-process-cpu-load-monitoring for more.


There does not seem to be a direct MBean within ManagementFactory. The closest is http://java.sun.com/javase/6/docs/api/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage() which can be used to calculate the CPU used by the whole system.

However this URL has suggested a method based on the source code of jconsole

Tags:

Jvm

Cpu Usage