How do I monitor the computer's CPU, memory, and disk usage in Java?

294,921

Solution 1

Along the lines of what I mentioned in this post. I recommend you use the SIGAR API. I use the SIGAR API in one of my own applications and it is great. You'll find it is stable, well supported, and full of useful examples. It is open-source with a GPL 2 Apache 2.0 license. Check it out. I have a feeling it will meet your needs.

Using Java and the Sigar API you can get Memory, CPU, Disk, Load-Average, Network Interface info and metrics, Process Table information, Route info, etc.

Solution 2

The following supposedly gets you CPU and RAM. See ManagementFactory for more details.

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

private static void printUsage() {
  OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
  for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
    method.setAccessible(true);
    if (method.getName().startsWith("get")
        && Modifier.isPublic(method.getModifiers())) {
            Object value;
        try {
            value = method.invoke(operatingSystemMXBean);
        } catch (Exception e) {
            value = e;
        } // try
        System.out.println(method.getName() + " = " + value);
    } // if
  } // for
}

Solution 3

In JDK 1.7, you can get system CPU and memory usage via com.sun.management.OperatingSystemMXBean. This is different than java.lang.management.OperatingSystemMXBean.

long getCommittedVirtualMemorySize()
// Returns the amount of virtual memory that is guaranteed to be available to the running process in bytes, or -1 if this operation is not supported.

long getFreePhysicalMemorySize()
// Returns the amount of free physical memory in bytes.

long getFreeSwapSpaceSize()
// Returns the amount of free swap space in bytes.

double getProcessCpuLoad()
// Returns the "recent cpu usage" for the Java Virtual Machine process.

long getProcessCpuTime()
// Returns the CPU time used by the process on which the Java virtual machine is running in nanoseconds.

double getSystemCpuLoad()
// Returns the "recent cpu usage" for the whole system.

long getTotalPhysicalMemorySize()
// Returns the total amount of physical memory in bytes.

long getTotalSwapSpaceSize()
// Returns the total amount of swap space in bytes.

Solution 4

This works for me perfectly without any external API, just native Java hidden feature :)

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());

Solution 5

Have a look at this very detailled article: http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking#UsingaSuninternalclasstogetJVMCPUtime

To get the percentage of CPU used, all you need is some simple maths:

MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer();

OperatingSystemMXBean osMBean = ManagementFactory.newPlatformMXBeanProxy(
mbsc, ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);

long nanoBefore = System.nanoTime();
long cpuBefore = osMBean.getProcessCpuTime();

// Call an expensive task, or sleep if you are monitoring a remote process

long cpuAfter = osMBean.getProcessCpuTime();
long nanoAfter = System.nanoTime();

long percent;
if (nanoAfter > nanoBefore)
 percent = ((cpuAfter-cpuBefore)*100L)/
   (nanoAfter-nanoBefore);
else percent = 0;

System.out.println("Cpu usage: "+percent+"%");

Note: You must import com.sun.management.OperatingSystemMXBean and not java.lang.management.OperatingSystemMXBean.

Share:
294,921

Related videos on Youtube

David Hergert
Author by

David Hergert

:)

Updated on August 13, 2021

Comments

  • David Hergert
    David Hergert almost 3 years

    I would like to monitor the following system information in Java:

    • Current CPU usage** (percent)
    • Available memory* (free/total)
    • Available disk space (free/total)

      *Note that I mean overall memory available to the whole system, not just the JVM.

    I'm looking for a cross-platform solution (Linux, Mac, and Windows) that doesn't rely on my own code calling external programs or using JNI. Although these are viable options, I would prefer not to maintain OS-specific code myself if someone already has a better solution.

    If there's a free library out there that does this in a reliable, cross-platform manner, that would be great (even if it makes external calls or uses native code itself).

    Any suggestions are much appreciated.

    To clarify, I would like to get the current CPU usage for the whole system, not just the Java process(es).

    The SIGAR API provides all the functionality I'm looking for in one package, so it's the best answer to my question so far. However, due it being licensed under the GPL, I cannot use it for my original purpose (a closed source, commercial product). It's possible that Hyperic may license SIGAR for commercial use, but I haven't looked into it. For my GPL projects, I will definitely consider SIGAR in the future.

    For my current needs, I'm leaning towards the following:

    • For CPU usage, OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors() (load average per cpu)
    • For memory, OperatingSystemMXBean.getTotalPhysicalMemorySize() and OperatingSystemMXBean.getFreePhysicalMemorySize()
    • For disk space, File.getTotalSpace() and File.getUsableSpace()

    Limitations:

    The getSystemLoadAverage() and disk space querying methods are only available under Java 6. Also, some JMX functionality may not be available to all platforms (i.e. it's been reported that getSystemLoadAverage() returns -1 on Windows).

    Although originally licensed under GPL, it has been changed to Apache 2.0, which can generally be used for closed source, commercial products.

    • Bomlin
      Bomlin over 15 years
      To clarify, the sigar api gets you system info. If you want jvm info use JMX.
    • Soundlink
      Soundlink over 13 years
      Since version 1.6.4 SIGAR is using the Apache license.
    • zcaudate
      zcaudate over 11 years
      do you know how to get the load for each individual processor?
  • blak3r
    blak3r almost 15 years
    Sample output for the code above. This code does work on Java 1.5. getCommittedVirtualMemorySize = 28622848 getFreePhysicalMemorySize = 228462592 getFreeSwapSpaceSize = 1129848832 getProcessCpuTime = 390625000 getTotalPhysicalMemorySize = 2147483647 getTotalSwapSpaceSize = 4294967295
  • Loving Android
    Loving Android almost 15 years
    AFAIK getProcessCpuTime = 390625000 is only how long that thread has been running. That is not really useful for determining the processor usage
  • Emmanuel Bourg
    Emmanuel Bourg almost 13 years
    Not sure it's actually reliable. On Windows XP with 4GB of physical memory it only reports 2GB (tested with Java 6 and Java 7). The total swap size is also wrong.
  • Donal Tobin
    Donal Tobin about 12 years
    This is actually what I was looking for, but the code is missing the REGEX pattern for finding the cpu information from the /proc/stat
  • Admin
    Admin over 11 years
    @EmmanuelBourg just to document for people who see this topic, there's a bug related to this.
  • tutejszy
    tutejszy over 11 years
    for me (Win XP) the proper command line was: typeperf "\processor(_total)\% processor time" If you put it to batch file, use %% instead of %. I used technet.microsoft.com/en-us/library/bb490960.aspx.
  • Alvaro
    Alvaro about 10 years
    Be careful when using Sigar, there are problems on x64 machines... stackoverflow.com/questions/23405832/… and it seems the library doesn't get updated since 2010
  • hcarrasko
    hcarrasko over 9 years
    what is the pattern ??
  • cen
    cen about 8 years
    Seems like this is hit and miss. Getting -1 for CPU load on FreeBSD 10 and OpenJDK 8.
  • ArsenArsen
    ArsenArsen over 7 years
    I honestly find this the best answer, works on Linux so I'm s happy fella.
  • vorburger
    vorburger almost 7 years
    any clue why a 2nd invocation shows 0.0 ? On OpenJDK v8.
  • Bernd
    Bernd over 6 years
    Don't forget: "import java.lang.management.ManagementFactory;"
  • Burak Akyıldız
    Burak Akyıldız about 6 years
    getProcessCpuLoad and getSystemCpuLoad return -1 form me. im using jdk 1.8
  • Juh_
    Juh_ almost 6 years
    check this question stackoverflow.com/q/19781087/1206998 . it says that it takes a couples seconds to be effective. (note: I didn't try)
  • djangofan
    djangofan over 5 years
    It doesn't have a method to get Thread count? Just wondering why?
  • gbmhunter
    gbmhunter over 5 years
    This one worked for me on both Windows 10 and macOS High Sierra.
  • Daniel Widdis
    Daniel Widdis about 5 years
    This works if you're using the Oracle JVM. If you have control of which Java version is installed, it's a great solution. It won't work with Open JDK, though, which more and more users are switching to since Oracle changed licensing requirements on JDK11.
  • Thor Lancaster
    Thor Lancaster almost 5 years
    This method worked great until Java 9, it now throws a java.lang.reflect.InaccessibleObjectException due to the new access checking framework Java is using.
  • Thor Lancaster
    Thor Lancaster almost 5 years
    This is THE right answer since Java 9. Looping through properties of the java.lang OperatingSystemMXBean instead of the com.sun one now throws an Exception.
  • Fractaly
    Fractaly almost 5 years
    This is a really good answer. All the other techniques give really weird and unreliable results, but this one with some trailing averaging worked like a charm for me.
  • Lukas Hanacek
    Lukas Hanacek about 4 years
    When the cpu time is higher than the elapsed time (I get over 100%), is it just because of multithreading, or how to understand it ?
  • RonPringadi
    RonPringadi over 3 years
    The link no longer works, what package is MBeanServerConnection?