Take the 2-minute tour ×

I'm currently building a Java app that could end up being run on many different platforms, but primarily variants of Solaris, Linux and Windows.

Has anyone been able to successfully extract information such as the current disk space used, CPU utilisation and memory used in the underlying OS? What about just what the Java app itself is consuming?

Preferrably I'd like to get this information without using JNI.

share|improve this question
add comment

11 Answers

up vote 116 down vote accepted

You can get some limited memory information from the Runtime class. It really isn't exactly what you are looking for, but I thought I would provide it for the sake of completeness. Here is a small example. Edit: You can also get disk usage information from the java.io.File class. The disk space usage stuff requires Java 1.6 or higher.

public class Main {
  public static void main(String[] args) {
    /* Total number of processors or cores available to the JVM */
    System.out.println("Available processors (cores): " + 

    /* Total amount of free memory available to the JVM */
    System.out.println("Free memory (bytes): " + 

    /* This will return Long.MAX_VALUE if there is no preset limit */
    long maxMemory = Runtime.getRuntime().maxMemory();
    /* Maximum amount of memory the JVM will attempt to use */
    System.out.println("Maximum memory (bytes): " + 
        (maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));

    /* Total memory currently available to the JVM */
    System.out.println("Total memory available to JVM (bytes): " + 

    /* Get a list of all filesystem roots on this system */
    File[] roots = File.listRoots();

    /* For each filesystem root, print some info */
    for (File root : roots) {
      System.out.println("File system root: " + root.getAbsolutePath());
      System.out.println("Total space (bytes): " + root.getTotalSpace());
      System.out.println("Free space (bytes): " + root.getFreeSpace());
      System.out.println("Usable space (bytes): " + root.getUsableSpace());
share|improve this answer
I think "Total memory currently in use by the JVM" is a little confusing. The javadoc says that function returns "the total amount of memory currently available for current and future objects, measured in bytes." Sounds more like memory remaining and not in use. –  Dirk Jun 30 '12 at 0:46
the performance of these functions is low? –  Leonardo Galdioli Jan 24 at 11:59
@Dirk: I updated the wording to address your comment. Thanks! –  William Brendel Jan 24 at 22:46
@LeonardoGaldioli: I don't know the performance characteristics of these classes and methods, but I wouldn't be surprised if they weren't optimized for speed. Other answers explain how to collect certain information using JMX, which might be faster. –  William Brendel Jan 24 at 22:46
This doesn't answer the question correctly. All that data reefers to JVM and not to the OS... –  Alvaro Feb 19 at 10:33
add comment

The java.lang.management package does give you a whole lot more info than Runtime - for example it will give you heap memory (ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()) separate from non-heap memory (ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()).

You can also get process CPU usage (without writing your own JNI code), but you need to cast the java.lang.management.OperatingSystemMXBean to a com.sun.management.OperatingSystemMXBean. This works on Windows and Linux, I haven't tested it elsewhere.

For example ... call the get getCpuUsage() method more frequently to get more accurate readings.

public class PerformanceMonitor { 
    private int  availableProcessors = getOperatingSystemMXBean().getAvailableProcessors();
    private long lastSystemTime      = 0;
    private long lastProcessCpuTime  = 0;

    public synchronized double getCpuUsage()
        if ( lastSystemTime == 0 )

        long systemTime     = System.nanoTime();
        long processCpuTime = 0;

        if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
            processCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();

        double cpuUsage = (double) ( processCpuTime - lastProcessCpuTime ) / ( systemTime - lastSystemTime );

        lastSystemTime     = systemTime;
        lastProcessCpuTime = processCpuTime;

        return cpuUsage / availableProcessors;

    private void baselineCounters()
        lastSystemTime = System.nanoTime();

        if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
            lastProcessCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();
share|improve this answer
The code doesn't compile... –  futureelite7 Jun 3 '10 at 4:38
To get it to compile, replace the cast OperatingSystemMXBean to com.sun.management.OperatingSystemMXBean and preface all instances of getOperatingSystemMXBean() with ManagementFactory.. You need to import all the classes appropriately. –  tmarthal Feb 10 '11 at 2:47
i'm getting cpu usage as 0 for everything. i changed the cpu usage formula to cpuUsage = processCpuTime / systemTime. i'm getting a value for cpu usage which i dont understand. –  Raj Feb 27 '12 at 11:08
does 1.0 as result from getCpuUsage mean that the system is using all its availableProcessors at 100%? –  user454322 Sep 5 '12 at 9:00
I always get 0 as @Raj said... could you give a example of how to use that code? –  dm76 Nov 28 '12 at 15:25
show 1 more comment

I think the best method out there is to implement the SIGAR API by Hyperic. It works for most of the major operating systems ( darn near anything modern ) and is very easy to work with. The developer(s) are very responsive on their forum and mailing lists. I also like that it is GPL2 Apache licensed. They provide a ton of examples in Java too!

SIGAR == System Information, Gathering And Reporting tool.

share|improve this answer
is this is platform independent? Please help! –  GloryOfSuccess Sep 9 '12 at 14:03
@Yohan - Don't be lazy! You can find that out by reading the linked webpage. (And it depends on what you mean by "platform independent".) –  Stephen C Feb 26 '13 at 6:10
@StephenC: Sigar is using .dll files, which makes it platform dependent. The higher level API might be in Java, it is a different story –  GloryOfSuccess Feb 26 '13 at 6:49
@Yohan - The Runtime and MxBean APIs only report on stuff related to the current JVM. SIGAR should give you much more. –  Stephen C Feb 26 '13 at 16:37
@Artificial_Intelligence yes, but it provides libraries (written in c) for most popular platforms. It is no more platform dependant than the jvm itself. The higher level Java API should be consistent on all platforms. –  Jeshurun Aug 21 '13 at 15:29
add comment

Have a look at the APIs available in the java.lang.management package. For example:

  • OperatingSystemMXBean.getSystemLoadAverage()
  • ThreadMXBean.getCurrentThreadCpuTime()
  • ThreadMXBean.getCurrentThreadUserTime()

There are loads of other useful things in there as well.

share|improve this answer
OperatingSystemMXBean.getSystemLoadAverage() is not implemented in windows because "its too expensive" –  MikeNereson Jul 14 '09 at 15:36
ThreadMXBean.getCurrentThreadCpuTime() only returns how long that thread has been running. Not the cpu usage percentage. –  MikeNereson Jul 14 '09 at 15:37
add comment

CPU usage isn't straightforward -- java.lang.management via com.sun.management.OperatingSystemMXBean.getProcessCpuTime comes close (see Patrick's excellent code snippet above) but note that it only gives access to time the CPU spent in your process. it won't tell you about CPU time spent in other processes, or even CPU time spent doing system activities related to your process.

for instance i have a network-intensive java process -- it's the only thing running and the CPU is at 99% but only 55% of that is reported as "processor CPU".

don't even get me started on "load average" as it's next to useless, despite being the only cpu-related item on the MX bean. if only sun in their occasional wisdom exposed something like "getTotalCpuTime"...

for serious CPU monitoring SIGAR mentioned by Matt seems the best bet.

share|improve this answer
add comment

You can get some system-level information by using System.getenv(), passing the relevant environment variable name as a parameter. For example, on Windows:


For other operating systems the presence/absence and names of the relevant environment variables will differ.

share|improve this answer
These are platform dependent because variable names are different among systems. Oracle article on environment variables tells that. I am also finding a way to get system independent way. –  GloryOfSuccess Sep 9 '12 at 14:02
add comment

Usually, to get low level OS information you can call OS specific commands which give you the information you want with Runtime.exec() or read files such as /proc/* in Linux.

share|improve this answer
add comment

There's a new native Java project that uses JNA (so no native libraries). It's very young and needs contributions.

share|improve this answer
No native libraries is perhaps misleading. The project uses native libraries, even if they haven't written any, and you apparently don't need to install any. –  Stephen C Apr 1 '11 at 11:06
You're right. JNA uses libffi that has native components. But for all purposes, it looks like there're no native libraries (definitely none to install). –  dB. May 12 '11 at 4:15
@StephenC although what you say is accurate, its misleading because its the same for rt.jar which also invokes native methods. the only reason people care about native methods is that they have to compile and/or install them, which is often often a non-trivial task. since libffi is so broadly adopted, ported, and installed, it mitigates the difficulties. so, technically you're correct, but practically, it doesn't matter. –  rbp Jun 7 '13 at 10:03
@rbp - There's another reason people why experienced Java developers prefer to avoid native libraries. A native library that has bugs (including thread safety issues or issues with memory management) is liable to destabilize the host JVM. This is not a "it doesn't matter" issue .... –  Stephen C Jun 7 '13 at 12:09
@StephenC does having authored the weblogic application server make me experienced enough? –  rbp Jun 7 '13 at 15:37
show 1 more comment

Hey you can do this with java/com integration. By accessing WMI features you can get all the information.

share|improve this answer
add comment

If you are using Jrockit VM then here is an other way of getting VM CPU usage. Runtime bean can also give you CPU load per processor. I have used this only on Red Hat Linux to observer Tomcat performance. You have to enable JMX remote in catalina.sh for this to work.

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://my.tomcat.host:8080/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);     
MBeanServerConnection conn = jmxc.getMBeanServerConnection();       
ObjectName name = new ObjectName("oracle.jrockit.management:type=Runtime");
Double jvmCpuLoad =(Double)conn.getAttribute(name, "VMGeneratedCPULoad");
share|improve this answer
add comment

You can try use follow library SystemInformation, try clone from GitHub and use.

share|improve this answer
add comment

protected by Community Feb 11 '12 at 6:54

