How do I monitor the computer's CPU, memory, and disk usage in Java?
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
.
Related videos on Youtube
Comments
-
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()
andOperatingSystemMXBean.getFreePhysicalMemorySize()
- For disk space,
File.getTotalSpace()
andFile.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 thatgetSystemLoadAverage()
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 over 15 yearsTo clarify, the sigar api gets you system info. If you want jvm info use JMX.
-
Soundlink over 13 yearsSince version 1.6.4 SIGAR is using the Apache license.
-
zcaudate over 11 yearsdo you know how to get the load for each individual processor?
-
blak3r almost 15 yearsSample 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 almost 15 yearsAFAIK getProcessCpuTime = 390625000 is only how long that thread has been running. That is not really useful for determining the processor usage
-
Emmanuel Bourg almost 13 yearsNot 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 about 12 yearsThis 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 over 11 years@EmmanuelBourg just to document for people who see this topic, there's a bug related to this.
-
tutejszy over 11 yearsfor 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 about 10 yearsBe 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 over 9 yearswhat is the pattern ??
-
cen about 8 yearsSeems like this is hit and miss. Getting -1 for CPU load on FreeBSD 10 and OpenJDK 8.
-
ArsenArsen over 7 yearsI honestly find this the best answer, works on Linux so I'm s happy fella.
-
vorburger almost 7 yearsany clue why a 2nd invocation shows 0.0 ? On OpenJDK v8.
-
Bernd over 6 yearsDon't forget: "import java.lang.management.ManagementFactory;"
-
Burak Akyıldız about 6 yearsgetProcessCpuLoad and getSystemCpuLoad return -1 form me. im using jdk 1.8
-
Juh_ almost 6 yearscheck this question stackoverflow.com/q/19781087/1206998 . it says that it takes a couples seconds to be effective. (note: I didn't try)
-
djangofan over 5 yearsIt doesn't have a method to get Thread count? Just wondering why?
-
gbmhunter over 5 yearsThis one worked for me on both Windows 10 and macOS High Sierra.
-
Daniel Widdis about 5 yearsThis 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 almost 5 yearsThis 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 almost 5 yearsThis 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 almost 5 yearsThis 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 about 4 yearsWhen 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 over 3 yearsThe link no longer works, what package is MBeanServerConnection?