英文:
How to get CPU utilization using Java 11
问题
我正在尝试使用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.9
。osBean.getAvailableProcessors()
返回8
。我很确定它是一颗英特尔四核心处理器,具有总共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;
}
英文:
I'm trying to get CPU utilization or usage using Java 11.
My expectation is the average percentage of total usage, I don't really have any interest in the number of cores or thread available on the CPU.
In simple term on 80% the CPU is very busy, and on 10% is more or less idling.
How do I get this?
I've been trying a couple of suggestions from stackoverflow.
Option 1. Using com.sun.management.OperatingSystemMXBean
is not good, anything com.sun
is old and should be avoided.
Option 2. There is a 3rd party org.hyperic.sigar.CpuInfo
which seems to be old and no longer maintained project. The result of cpuInfo.getVendor(), cpuInfo.getModel()
below is null null
. That gives me confidence (sacarsm).
protected void getCPUUtilization4() {
CpuInfo cpuInfo = new CpuInfo();
System.out.println(String.format(" CpuInfo: %s %s", cpuInfo.getVendor(), cpuInfo.getModel()));
}
Option 3. Built-in inside Java java.lang.management.OperatingSystemMXBean
. The problem with this option is the osBean.getSystemLoadAverage()
is a double
value. When my cpu is not busy ~ 1.3
, and when my CPU is busy reached up to ~2.9
. The osBean.getAvailableProcessors()
returns 8
. I'm pretty sure it's an Intel Quad core with total of 8 threads. Doesn't matter, how do I make sense of these numbers?
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使用饱和。
英文:
With the introduction of the module system, the type com.sun.management.OperatingSystemMXBean
has become part of the official API, but for modular software, there must be a declared dependency to the module jdk.management
rather than just java.management
.
So you can officially use
double cpuLoad = ManagementFactory.getPlatformMXBean(
com.sun.management.OperatingSystemMXBean.class).getCpuLoad();
but it’s also possible to access the JMX attribute dynamically, to avoid a strong code dependency:
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);
}
<sup>Prior to JDK 14, use getSystemCpuLoad()
or "SystemCpuLoad"
instead of getCpuLoad()
resp. "CpuLoad"
</sup>
This will not force the availability of the extension, but use it when available.
The system load average is, simply said, the average number of processes competing for the CPU. So for a single CPU system, you can say, a value of more than one not only means that the CPU was entirely busy, but the runnable tasks would have used more CPU resources when they were available.
For n CPUs or cores, you could say a similar thing when the system load reached the value n, but mind that this is only an average. So with a load value of n there still could have been a peek load where more than n application competed for the CPU, followed by some under-utilization of the CPU cores. But with enough sample values or a sufficiently high sampling rate, you can say that a value of n or higher implies a CPU usage saturation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论