如何使用Java 11获取CPU利用率

5

我正在尝试使用Java 11获取CPU利用率或使用情况。

我的期望是总使用率的平均百分比,我对CPU上可用的核心数或线程数并不感兴趣。

简单来说,在80%时,CPU非常忙碌,在10%左右则基本上处于闲置状态。

我该如何获得这个信息?

我已经尝试了一些stackoverflow上的建议。

选项1:使用com.sun.management.OperatingSystemMXBean不好,任何com.sun都已经过时,应该避免使用。

选项2:有一个第三方库org.hyperic.sigar.CpuInfo,但该项目似乎已经过时且不再维护。下面的cpuInfo.getVendor(),cpuInfo.getModel()的结果是null null。这给了我信心(讽刺)。

protected void getCPUUtilization4() {
        CpuInfo cpuInfo =  new CpuInfo();
        System.out.println(String.format("    CpuInfo: %s %s", cpuInfo.getVendor(), cpuInfo.getModel()));
    }

选项3:内置在Java的java.lang.management.OperatingSystemMXBean中。这个选项的问题是osBean.getSystemLoadAverage()返回的是一个double值。当我的CPU处于空闲状态时,它约为1.3,当我的CPU繁忙时,它可以达到约2.9osBean.getAvailableProcessors()返回8。我相当确定这是一颗Intel四核心处理器,具有总共8个线程。但这些数字意味着什么呢?

protected double getCPUUtilization5() {
        OperatingSystemMXBean osBean =
            ManagementFactory.getOperatingSystemMXBean();
        if (startSystemAverage == null) {
            startSystemAverage = osBean.getSystemLoadAverage();
            peakSystemAverage = osBean.getSystemLoadAverage();
        }
        if (peakSystemAverage < osBean.getSystemLoadAverage()) {
            peakSystemAverage = osBean.getSystemLoadAverage();
        }
        
        double sysAvg = osBean.getSystemLoadAverage();
        logger.info("    getCPUUtilization5: "+ sysAvg + " num of processors: "+ osBean.getAvailableProcessors());
        return sysAvg;
        
    }

1个回答

7

随着模块系统的引入,类型com.sun.management.OperatingSystemMXBean已成为官方API的一部分,但对于模块化软件,必须声明依赖于模块jdk.management而不是仅依赖于java.management

因此,您可以正式使用它。

double cpuLoad = ManagementFactory.getPlatformMXBean(
    com.sun.management.OperatingSystemMXBean.class).getCpuLoad();

但是也可以动态访问JMX属性,以避免强代码依赖:

try {
    double cpuLoad = (Double)ManagementFactory.getPlatformMBeanServer()
        .getAttribute(new ObjectName("java.lang:type=OperatingSystem"), "CpuLoad");
    …
} catch (JMException ex) {
    System.getLogger(CPULoad.class.getName()).log(System.Logger.Level.ERROR, "", ex);
}

在JDK 14之前,可以使用getSystemCpuLoad()"SystemCpuLoad"代替getCpuLoad()"CpuLoad"

这不会强制提供扩展,但在可用时使用它。


系统负载平均值,简单说来,是竞争CPU的进程的平均数量。因此,在单个CPU系统上,您可以说,大于1的值不仅意味着CPU完全繁忙,而且可运行任务在其可用时将使用更多的CPU资源。

对于n个CPU或核心,当系统负载达到值n时,您也可以说类似的事情,但请注意,这只是平均值。因此,负载值为n仍可能存在超过n个应用程序竞争CPU的峰值负载,然后是某些CPU核心的未充分利用。但是,通过足够的样本值或足够高的采样率,您可以说n或更高的值意味着CPU使用饱和。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接