src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c did not properly initialize counters.jvmTicks an counters.cpuTicks in perfInit() method. Function get_cpuload_internal(...) calls get_totalticks() and get_jvmticks() functions that update these counters. But on the first call, it used to compare the newly received counters with the garbage.
The missed initialization was fixed in JDK-8226575, however, there is a code in get_cpuload_internal(...) method that seems to be written to somehow mitigate the missed initialization and in worse case just return 0 or 1.0. But it also could be that there is some other problem this code tries to solve. This issue is filed to look into this and remove these workarounds.
// seems like we sometimes end up with less kernel ticks when
// reading /proc/self/stat a second time, timing issue between cpus?
if (pticks->usedKernel < tmp.usedKernel) {
kdiff = 0;
} else {
kdiff = pticks->usedKernel - tmp.usedKernel;
}
tdiff = pticks->total - tmp.total;
udiff = pticks->used - tmp.used;
if (tdiff == 0) {
user_load = 0;
} else {
if (tdiff < (udiff + kdiff)) {
tdiff = udiff + kdiff;
}
*pkernelLoad = (kdiff / (double)tdiff);
// BUG9044876, normalize return values to sane values
*pkernelLoad = MAX(*pkernelLoad, 0.0);
*pkernelLoad = MIN(*pkernelLoad, 1.0);
user_load = (udiff / (double)tdiff);
user_load = MAX(user_load, 0.0);
user_load = MIN(user_load, 1.0);
}