Hidden Java 7 Features – System and Process CPU Load Monitoring
A couple of weeks ago I wrote a summary of 7 new cool features in Java 7. Others have written great blog posts about them, so I was thinking it might be useful for me to focus on lesser known or “Hidden Java 7 Features”. In the next few weeks, I’ll try to explore and write a series of blog posts about them.
System and Process CPU Load Monitoring
Java 7 provides a new MBean that finally allows Java developers to access overall System and current process CPU load monitoring. This feature is not really that hidden as it’s listed in the what’s new page for JDK 7, but I haven’t really noticed a lot of talk about it and I certainly overlooked it initially.
The interface com.sun.management.OperatingSystemMXBean, has two new methods that easily get this information; getSystemCpuLoad() and getProcessCpuLoad(). Both methods return the load as a double value in the [0.0,1.0] interval, with 0.0 representing no load to 1.0 representing 100% CPU load for the whole system or the current JVM process respectively.
It’s pretty easy to get access to this MBean;
import com.sun.management.OperatingSystemMXBean; ... OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean( OperatingSystemMXBean.class); // What % CPU load this current JVM is taking, from 0.0-1.0 System.out.println(osBean.getProcessCpuLoad()); // What % load the overall system is at, from 0.0-1.0 System.out.println(osBean.getSystemCpuLoad());
Wasn’t this already available?
Java 6 introduced a new method in java.lang.management.OperatingSystemMXBean called getSystemLoadAverage(), which could get the CPU average for the overall system (there wasn’t a mechanism for the JVM/current process load). However this doesn’t seem to work on Windows and would just return a -1 (tried this with Java 7 in Windows 7 and that is still the case).
Other ways of doing this prior to Java 7 would include Java APIs implemented via native libraries like SIGAR, which are good alternatives but obviously not part of the standard Java distribution, or may not support most platforms.
Now the bad news
If you notice in my code I use com.sun.management.OperatingSystemMXBean, not java.lang.management.OperatingSystemMXBean which means the methods getSystemCpuLoad() and getProcessCpuLoad() are not part of the official, supported public interface of the Java Platform. Oracle actually discourages the use of these packages, since they could be removed in future releases or may not be available in all JVM implementations.
I’m not 100% sure why these methods were only added to the com.sun version of OperatingSystemMXBean. Initially I thought it was because Oracle didn’t want to add a method to a public interface (which would break any code implementing that interface), however Java 6 added getSystemLoadAverage(). If anybody has any insight on this, please let me know.
There are ways to use these new methods without having a hard dependency to these com.sun classes (for example via reflection, or using JMX conventions), I may cover these in a future blog post or update to this one.
Finally, I wanted to do a simple UI that would use this feature to have a little widget to monitor system CPU and current process load graphically. I call it “JCPMon”, it can be launched as a standalone Java application, run inside an application you want to monitor or just used as a Swing component in a Java UI.
The green part of the graph represents the overall system CPU load, while the yellow part represents the current process load, in this case CPU load imposed by the GUI (I did a lot of resizing to get a few yellow bars for this image ). If you want to monitor a Java application you already have, you can easily do so by calling;
// This method won't block, so you can call it at the start of your program com.sellmic.apps.monitoring.jcpumon.Main(null); // And then continue doing anything else ...
Of course an improvement would be to have the ability to connect to an external process via JMX (remote or local).
This simple GUI uses this new Java 7 capability and also has some extras to configure the look of the UI (squares or circles, size, how often to update, always on top, full screen). If anybody is interested in the code for this let me know and I can setup a page to host it.
UPDATE: JNLP URL was wrong, if you tried webstart before and it failed please try again. Sorry about that!