【问题标题】:Calculate the CPU usage properly using the Java Management API on Windows machine在 Windows 机器上使用 Java 管理 API 正确计算 CPU 使用率
【发布时间】:2017-09-15 14:04:26
【问题描述】:

我想实现一个测试程序,该程序正确地使用 Java 管理 API 计算 CPU 使用率。结果应该是所有处理器及其内核的算术平均值。 windows机器上的问题是标准方法

ManagementFactory.getOperatingSystemMXBean().

(a) getSystemLoadAverage()
(b) getProcessCpuLoad()
(c) getSystemCpuLoad()

太频繁地传递值-1.00,这意味着无法计算cpu使用率。标准方法在 linux 上运行良好,但在 windows 上不行。我也在这个论坛中搜索了解决方案。我在这个论坛中找到了一些解决这个问题的方法,但它们都对我没有帮助。例如,下面的代码总是在我的机器上计算 16%,这是不现实的。

public synchronized double getCpuUsage() {
    double cpuPercent = 0.0;

    for (int i = 0; i < 30; i++) {
        long start = System.nanoTime();
        int cpuCount = getOperatingSystemMxBean().getAvailableProcessors();
        Random random = new Random(start);
        int seed = Math.abs(random.nextInt());
        int primes = 10000;
        long startCpuTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
        start = System.nanoTime();
        while (primes != 0) {
            if (isPrime(seed))
            {
                primes--;
            }
            seed++;
        } 

        cpuPercent = calcCpu(startCpuTime, start, cpuCount);

        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return cpuPercent;
}

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 divisory 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 int calcCpu(long cpuStartTime, long elapsedStartTime, int cpuCount) {
    long end = System.nanoTime();
    long totalAvailCpuTime = cpuCount * (end - elapsedStartTime);
    long totalUsedCpuTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime() - cpuStartTime;
    float per = ((float)totalUsedCpuTime*100) / (float)totalAvailCpuTime;
    //log (per);
    return (int)per;
}

private OperatingSystemMXBean getOperatingSystemMxBean() {
    return (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
}

你知道这个问题的正确解决方案吗?

【问题讨论】:

  • 您可能希望包含指向您已经咨询过的其他 SO 问题的真实链接。也许你需要一些 JNI 接口来连接一些真正的 Windows 系统调用。
  • 链接到其他CPU使用问题:stackoverflow.com/questions/47177/…
  • JNI接口如何使用?
  • 通过 A) 确定合适的系统接口,然后 B) 对 JNI 进行研究。不要指望别人做你的工作。
  • 我需要一个纯 Java 解决方案,而不是使用 C 函数

标签: java cpu-usage


【解决方案1】:

我通过使用库 oshi 解决了 windows 机器中的问题。在 Solaris 和 Linux 上,我继续使用 Java Management API。

【讨论】:

    猜你喜欢
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多