如何在Java中监视计算机的CPU,内存和磁盘使用情况?

我想在Java中监视以下系统信息:

  • 当前CPU使用率**(百分比)
  • 可用内存*(免费/总计)
  • 可用磁盘空间(免费/总计)

    *请注意,我的意思是整个系统可用的全部内存,而不仅仅是JVM。

我正在寻找一种跨平台的解决scheme(Linux,Mac和Windows),它不依赖我自己的调用外部程序或使用JNI的代码。 虽然这些是可行的select,但如果有人已经有了更好的解决scheme,我宁愿不自己维护特定于操作系统的代码。

如果有一个免费的库,它以可靠的,跨平台的方式做到这一点,这将是伟大的(即使它使外部调用或使用本机代码本身)。

任何build议,非常感谢。

为了澄清,我想获得整个系统的当前CPU使用率,而不仅仅是Java进程。

SIGAR API提供了我正在寻找的所有function,所以这是迄今为止我的问题的最佳答案。 但是,由于它是根据GPL许可的,我不能将其用于我原来的目的(封闭源代码,商业产品)。 Hyperic有可能将SIGAR许可用于商业用途,但我没有仔细研究过它。 对于我的GPL项目,我将来肯定会考虑SIGAR。

对于我目前的需求,我倾向于以下几点:

  • 对于CPU使用率,OperatingSystemMXBean.getSystemLoadAverage()/ OperatingSystemMXBean.getAvailableProcessors()(每个CPU的平均负载)
  • 对于内存,OperatingSystemMXBean.getTotalPhysicalMemorySize()和OperatingSystemMXBean.getFreePhysicalMemorySize()
  • 对于磁盘空间,File.getTotalSpace()和File.getUsableSpace()

限制:

getSystemLoadAverage()和磁盘空间查询方法仅在Java 6下可用。另外,某些JMXfunction可能不适用于所有平台(即,据报道getSystemLoadAverage()在Windows上返回-1)。

虽然最初是根据GPL授权的,但它已经改为 Apache 2.0 ,通常可以用于封闭源代码的商业产品。

沿着我在这篇文章中提到的路线。 我build议你使用SIGAR API 。 我在我自己的应用程序中使用了SIGAR API,这非常棒。 你会发现它是稳定的,很好的支持,并且有很多有用的例子。 它是一个开源的GPL 2 Apache 2.0许可证。 一探究竟。 我有一种感觉,它会满足你的需求。

使用Java和Sigar API,您可以获得内存,CPU,磁盘,负载平均,networking接口信息和度量,处理表信息,路由信息等。

以下应该得到你的CPU和内存。 有关更多详细信息,请参阅ManagementFactory 。

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 } 

在JDK 1.7中,可以通过com.sun.management.OperatingSystemMXBean获取系统CPU和内存的使用情况。 这与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. 

看看这个非常详细的文章: http : //nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking#UsingaSuninternalclasstogetJVMCPUtime

为了获得所使用的CPU的百分比,所有你需要的是一些简单的math:

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

注意:您必须导入com.sun.management.OperatingSystemMXBean而不是java.lang.management.OperatingSystemMXBean

这对我完全没有任何外部的API,只是本地Java隐藏的function:)

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

对于磁盘空间,如果您有Java 6,则可以在File上使用getTotalSpace和getFreeSpace方法。 如果你不在Java 6上,我相信你可以使用Apache Commons IO来获得一些方法。

我不知道任何跨平台的方式来获取CPU使用率或内存使用恐怕。

很多这个已经可以通过JMX获得了。 对于Java 5,JMX是内置的,它们包含一个带有JDK的JMX控制台查看器。

如果您在自己的运行时需要这些信息,则可以使用JMX手动进行监视,或者从Java调用JMX命令。

 /* YOU CAN TRY THIS TOO */ import java.io.File; import java.lang.management.ManagementFactory; // import java.lang.management.OperatingSystemMXBean; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.management.RuntimeMXBean; import java.io.*; import java.net.*; import java.util.*; import java.io.LineNumberReader; import java.lang.management.ManagementFactory; import com.sun.management.OperatingSystemMXBean; import java.lang.management.ManagementFactory; import java.util.Random; public class Pragati { public static void printUsage(Runtime runtime) { long total, free, used; int mb = 1024*1024; total = runtime.totalMemory(); free = runtime.freeMemory(); used = total - free; System.out.println("\nTotal Memory: " + total / mb + "MB"); System.out.println(" Memory Used: " + used / mb + "MB"); System.out.println(" Memory Free: " + free / mb + "MB"); System.out.println("Percent Used: " + ((double)used/(double)total)*100 + "%"); System.out.println("Percent Free: " + ((double)free/(double)total)*100 + "%"); } public static void log(Object message) { System.out.println(message); } public static int calcCPU(long cpuStartTime, long elapsedStartTime, int cpuCount) { long end = System.nanoTime(); long totalAvailCPUTime = cpuCount * (end-elapsedStartTime); long totalUsedCPUTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime()-cpuStartTime; //log("Total CPU Time:" + totalUsedCPUTime + " ns."); //log("Total Avail CPU Time:" + totalAvailCPUTime + " ns."); float per = ((float)totalUsedCPUTime*100)/(float)totalAvailCPUTime; log( per); return (int)per; } static boolean isPrime(int n) { // 2 is the smallest prime if (n <= 2) { return n == 2; } // even numbers other than 2 are not prime if (n % 2 == 0) { return false; } // check odd divisors from 3 // to the square root of n for (int i = 3, end = (int)Math.sqrt(n); i <= end; i += 2) { if (n % i == 0) { return false; } } return true; } public static void main(String [] args) { int mb = 1024*1024; int gb = 1024*1024*1024; /* PHYSICAL MEMORY USAGE */ System.out.println("\n**** Sizes in Mega Bytes ****\n"); com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean(); //RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); //operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean(); long physicalMemorySize = os.getTotalPhysicalMemorySize(); System.out.println("PHYSICAL MEMORY DETAILS \n"); System.out.println("total physical memory : " + physicalMemorySize / mb + "MB "); long physicalfreeMemorySize = os.getFreePhysicalMemorySize(); System.out.println("total free physical memory : " + physicalfreeMemorySize / mb + "MB"); /* DISC SPACE DETAILS */ File diskPartition = new File("C:"); File diskPartition1 = new File("D:"); File diskPartition2 = new File("E:"); long totalCapacity = diskPartition.getTotalSpace() / gb; long totalCapacity1 = diskPartition1.getTotalSpace() / gb; double freePartitionSpace = diskPartition.getFreeSpace() / gb; double freePartitionSpace1 = diskPartition1.getFreeSpace() / gb; double freePartitionSpace2 = diskPartition2.getFreeSpace() / gb; double usablePatitionSpace = diskPartition.getUsableSpace() / gb; System.out.println("\n**** Sizes in Giga Bytes ****\n"); System.out.println("DISC SPACE DETAILS \n"); //System.out.println("Total C partition size : " + totalCapacity + "GB"); //System.out.println("Usable Space : " + usablePatitionSpace + "GB"); System.out.println("Free Space in drive C: : " + freePartitionSpace + "GB"); System.out.println("Free Space in drive D: : " + freePartitionSpace1 + "GB"); System.out.println("Free Space in drive E: " + freePartitionSpace2 + "GB"); if(freePartitionSpace <= totalCapacity%10 || freePartitionSpace1 <= totalCapacity1%10) { System.out.println(" !!!alert!!!!"); } else System.out.println("no alert"); Runtime runtime; byte[] bytes; System.out.println("\n \n**MEMORY DETAILS ** \n"); // Print initial memory usage. runtime = Runtime.getRuntime(); printUsage(runtime); // Allocate a 1 Megabyte and print memory usage bytes = new byte[1024*1024]; printUsage(runtime); bytes = null; // Invoke garbage collector to reclaim the allocated memory. runtime.gc(); // Wait 5 seconds to give garbage collector a chance to run try { Thread.sleep(5000); } catch(InterruptedException e) { e.printStackTrace(); return; } // Total memory will probably be the same as the second printUsage call, // but the free memory should be about 1 Megabyte larger if garbage // collection kicked in. printUsage(runtime); for(int i = 0; i < 30; i++) { long start = System.nanoTime(); // log(start); //number of available processors; int cpuCount = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors(); Random random = new Random(start); int seed = Math.abs(random.nextInt()); log("\n \n CPU USAGE DETAILS \n\n"); log("Starting Test with " + cpuCount + " CPUs and random number:" + seed); int primes = 10000; // long startCPUTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime(); start = System.nanoTime(); while(primes != 0) { if(isPrime(seed)) { primes--; } seed++; } float cpuPercent = calcCPU(startCPUTime, start, cpuCount); log("CPU USAGE : " + cpuPercent + " % "); try { Thread.sleep(1000); } catch (InterruptedException e) {} } try { Thread.sleep(500); }`enter code here` catch (Exception ignored) { } } } 

创build一个batch file“Pc.bat”,typeperf -sc 1“\ mukit \ processor(_Total)\ %% Processor Time”

你可以使用MProcess类,

 / *
  *马里兰州。  Mukit Hasan
  * CSE-JU,35
  ** /
 import java.io. *; 

公共类MProcessor {

public MProcessor() { String s; try { Process ps = Runtime.getRuntime().exec("Pc.bat"); BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream())); while((s = br.readLine()) != null) { System.out.println(s); } } catch( Exception ex ) { System.out.println(ex.toString()); } }

}

然后在一些string操作之后,你得到了CPU的使用。 您可以对其他任务使用相同的过程。

–Mukit Hasan

下面的代码只是Linux(也许是Unix),但它在一个真实的项目中工作。

  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; }