views:

17752

answers:

9

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, 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.

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

EDIT: 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:

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).

+4  A: 

For disk space, if you have Java 6, you can use the getTotalSpace and getFreeSpace methods on File. If you're not on Java 6, I believe you can use Apache Commons IO to get some of the way there.

I don't know of any cross platform way to get CPU usage or Memory usage I'm afraid.

Matt Sheppard
+7  A: 

What I found by Googling. This 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
}
eed3si9n
Sample output for the code above. This code does work on Java 1.5. getCommittedVirtualMemorySize = 28622848getFreePhysicalMemorySize = 228462592getFreeSwapSpaceSize = 1129848832getProcessCpuTime = 390625000getTotalPhysicalMemorySize = 2147483647getTotalSwapSpaceSize = 4294967295
blak3r
AFAIK getProcessCpuTime = 390625000 is only how long that thread has been running. That is not really useful for determining the processor usage
MikeNereson
+13  A: 

Along the lines of what I mentioned in this post; I recommend you use the SIGAR API ( I am not associated with it/them in any way - but, 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 GPL2 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.

SIGAR API by Hyperic

Matt Cummings
You should not have to say that you are "not associated with it/them in any way" It's useless info IMHO
Frederic Morin
Thanks, the SIGAR API certainly provides the necessary functionality. Unfortunately for me, it's licensed under the GPL, which prevents me from being able to use it in my current situation. Aside from that, it would be perfect. :(
David Crow
+1  A: 

A lot of this is already available via JMX. With Java 5, JMX is built-in and they include a JMX console viewer with the JDK.

You can use JMX to monitor manually, or invoke JMX commands from Java if you need this information in your own run-time.

Jason Cohen
A: 

This code is linux (maybe unix) only, but it works in real project

    private double getAverageValueByLinux() throws InterruptedException {
 try {

  long delay = 50;
  List<Double> listValues = new ArrayList<Double>();
  for (int i = 0; i < 100; i++) {
   long cput1 = getCpuT(pattern);
   Thread.sleep(delay);
   long cput2 = getCpuT(pattern);
   double cpuproc = (1000d * (cput2 - cput1)) / (double) delay;
   listValues.add(cpuproc);
  }
  listValues.remove(0);
  listValues.remove(listValues.size() - 1);
  double sum = 0.0;
  for (Double double1 : listValues) {
   sum += double1;
  }
  return sum / listValues.size();
 } catch (Exception e) {
  e.printStackTrace();
  return 0;
 }

}

private long getCpuT(Pattern pattern) throws FileNotFoundException, IOException {
 BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));
 String line = reader.readLine();
 Matcher m = pattern.matcher(line);

 long cpuUser = 0;
 long cpuSystem = 0;
 if (m.find()) {
  cpuUser = Long.parseLong(m.group(1));
  cpuSystem = Long.parseLong(m.group(3));
 }
 return cpuUser + cpuSystem;
}
A: 

hi david..

i was planning to develop the same project. I've been searching for a very long time until somebody suggest me to use SIGAR. I have downloaded sigar but I dont understand how to use it. Can someone please guide me? I've try to run using this command java -jar sigar.java but i got this error message: unable to access jarfile sigar.java please help:(

rose
A: 

Dear I need to know how to get the Motherboard Hardware ID or the Processor ID to run only my program for a specific Machine how i can do that?

FEDORA
This looks like it's a separate question, not in the topic of this question.
Steve Armstrong
A: 
Md. Mukit Hasan
+1  A: 

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+"%");