首页 > 解决方案 > Window Task CPU Utilization 和 Oshi CPU 使用率的区别

问题描述

我使用 Oshi API ( https://github.com/oshi/oshi ) 来获取 CPU 使用率。但是,为什么该值与任务管理器 CPU 利用率不同?我的错误是什么?

我的计划 - 平均 11.13%

在此处输入图像描述

任务管理器 - 平均约 29%

在此处输入图像描述

编辑代码

private SystemInfo systemInformation = new SystemInfo();
private CentralProcessor proc = systemInformation.getHardware().getProcessor();

private static float[] floatArrayPercent(double d) {
  float[] f = new float[1];
  f[0] = (float) (100d * d);
  return f;
}

private double cpuData(CentralProcessor proc) {
  double d = proc.getSystemCpuLoadBetweenTicks(oldTicks);
  oldTicks = proc.getSystemCpuLoadTicks();
  return d;
}


@Scheduled(fixedRate = 10)
public void processProcessorInformation() {
  System.out.println("The percentage of the floating value  cpu: " + floatArrayPercent(cpuData(proc))[0]);
}

标签: javaoshi

解决方案


问题是,当您打算进行“最近”使用计算时,您有一行代码将其重置为累积(自启动以来)使用计算。

getSystemCpuLoadBetweenTicks(oldTicks)计算测量从当前计数器到您传递给它的先前计数器的经过的用户、系统、空闲等滴答声,并为您提供这些时间片之间的使用情况。在您的cpuData()方法中,您正确保存了旧的刻度,并且可能打算再次使用它们。那部分是正确的。

但是,在您每次 processProcessorInformation()将数组归零时: . 因此,返回的值是自您开始以来的累积平均 CPU 使用率,而不是最后 10 秒。删除该行(或将其移出预定方法)应该会给您预期的结果。oldTicksoldTicks = new long[TickType.values().length];

您也不需要cpu每次都获得对象的新副本。您可以在移动初始化时将该初始化移出计划的方法oldTicks

在相关说明中,@Elliot-Frisch 在评论中提到了涉及多个处理器的计算。在比较处理器滴答与时间时(例如,如果您正在测量经过的时间段之间的滴答),这是一个有用的警告。滴答声在每个逻辑处理器上累积,因此您需要确保缩放“经过时间”以包括每个逻辑处理器。这适用于处理每个进程的 CPU 计算,因为您只有可用的进程运行时间作为分母,在这种情况下,Windows 任务管理器被缩放以确保没有进程超过 100%,而 *nix 结果 (on top) 不会被缩放并且有可能超过 100%。

但是,对于系统 CPU 使用率,我们有一个可用的“空闲”滴答计数器,它确实会在所有处理器上累积滴答,并且是计算百分比使用率的更好选择——并且是该getSystemCpuLoadBetweenTicks()方法中使用的,因此不需要进行此更正.


推荐阅读