我想用Java监控以下系统信息:

当前CPU使用率**(百分比) 可用内存*(空闲/总) 可用磁盘空间(空闲/总) *注意,我指的是整个系统可用的全部内存,而不仅仅是JVM。

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

如果有一个免费的库能够以可靠的、跨平台的方式做到这一点,那就太好了(即使它进行外部调用或使用本机代码本身)。

任何建议都非常感谢。

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

SIGAR API在一个包中提供了我正在寻找的所有功能,因此它是迄今为止对我的问题的最佳答案。然而,由于它是在GPL下授权的,我不能将它用于我最初的目的(一个封闭源代码的商业产品)。Hyperic可能会授权SIGAR用于商业用途,但我还没有调查过。对于我的GPL项目,我将来肯定会考虑SIGAR。

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

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

限制:

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

虽然最初是在GPL下授权的,但它已经被更改为Apache 2.0,通常可以用于闭源的商业产品。


当前回答

制作一个批处理文件“Pc.bat”,如下: typeperf -sc 1 "\mukit\processor(_Total)\%%处理器时间"

你可以使用类MProcess,

- * * Md。Mukit哈桑 * 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()); } }

}

然后在一些字符串操作之后,就得到了CPU使用情况。您可以对其他任务使用相同的流程。

——Mukit哈桑

其他回答

这对我来说是完美的,没有任何外部API,只是本地Java隐藏功能:)

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

在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使用的百分比,你只需要做一些简单的数学运算:

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。

制作一个批处理文件“Pc.bat”,如下: typeperf -sc 1 "\mukit\processor(_Total)\%%处理器时间"

你可以使用类MProcess,

- * * Md。Mukit哈桑 * 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()); } }

}

然后在一些字符串操作之后,就得到了CPU使用情况。您可以对其他任务使用相同的流程。

——Mukit哈桑

下面的代码只适用于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();
            Thread.sleep(delay);
            long cput2 = getCpuT();
            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 throws FileNotFoundException, IOException {
    BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));
    String line = reader.readLine();
    Pattern pattern = Pattern.compile("\\D+(\\d+)\\D+(\\d+)\\D+(\\d+)\\D+(\\d+)")
    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;
}