I tried to get current CPU load:
while (true) {
OperatingSystemMXBean os = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
System.out.println("CPU Load: " + os.getCpuLoad() * 100 + "%");
}
To my surprise, it is always 0! Note that in the mean time, I am running stress --cpu 4, and therefore the actual CPU load is around 20%. I checked out the JDK doc:
Returns the "recent cpu usage" for the operating environment.
However, if I add Thread.sleep(1000) inside the while loop, then the result is expected. It seems that some time gaps are required between calling getCpuLoad() because it needs to collect some system statics in that interval.
I also tried to print the CPU load after the sleeping (without any loop, only twice of printing):
Thread.sleep(1000);
OperatingSystemMXBean os = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
Thread.sleep(1000);
System.out.println(os.getCpuLoad() * 100 + "%"); // still always 0%
Thread.sleep(1000);
System.out.println(os.getCpuLoad() * 100 + "%"); // about 20%
The result shows that the first calling of getCpuLoad() will always return 0. I think it is really confusing.
Is it a pitfall of JDK's implementation? Why does not JDK doc add warnings about its usage?
My settings:
Good one.
On my machine (macos 13.2) jdk 17.06 demonstrates the same behaviour. It does seem to be an implementation detail .
please see the code by the link below: https://github.com/openjdk/jdk/blob/master/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c
if (last_used == 0 || last_total == 0) {
// First call, just set the last values
last_used = used;
last_total = total;
// return 0 since we have no data, not -1 which indicates error
return 0;
}
it's a bummer though, that they didn't specify this in the docs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With