-
Bug
-
Resolution: Fixed
-
P4
-
8u191, 10, 11, 12, 13, 14
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8257157 | 13.0.6 | Ekaterina Vergizova | P4 | Resolved | Fixed | b02 |
JDK-8253783 | 11.0.10-oracle | Bob Vandette | P4 | Resolved | Fixed | b01 |
JDK-8253983 | 11.0.10 | Bob Vandette | P4 | Resolved | Fixed | b01 |
JDK-8256947 | openjdk8u282 | Bob Vandette | P4 | Resolved | Fixed | b04 |
JDK-8254037 | 8u281 | Harold Seigel | P4 | Resolved | Fixed | b01 |
JDK-8257283 | emb-8u281 | Harold Seigel | P4 | Resolved | Fixed | team |
This does seem to be somewhat hardware dependent - some VMs don't exhibit the problem, and we haven't seen this on Windows yet. We've seen this on Linux 64-bit Openstack VMs, in at least 3 different setups.
A DESCRIPTION OF THE PROBLEM :
We have observed a significant performance regression in the Runtime.availableProcessors native API call.
On JDK versions prior to 1.8b191, a simple program can achieve upwards of 4 million calls to Runtime.availableProcessors a second on our test hardware.
On JDK build 1.8b191 and all later major and minor versions, including 11, the maximum it can achieve is around 40,000 calls a second - a performance drop of 100x.
This causes performance issues for CompletableFuture.waitingGet, which calls Runtime.availableProcessors in a tight loop as part of its spinwait - which is how we originally found the issue, as our application was exhibiting significant performance problems in our asynchronous code.
REGRESSION : Last worked in version 8u192
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached program on JDK version 1.8b182, and 1.8b191, on a 64bit Linux machine.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The performance should be the same
ACTUAL -
The performance drops by a factor of 100.
---------- BEGIN SOURCE ----------
public static void main(String[] args) throws Exception {
AtomicBoolean stop = new AtomicBoolean();
AtomicInteger count = new AtomicInteger();
new Thread(() -> {
while (!stop.get()) {
Runtime.getRuntime().availableProcessors();
count.incrementAndGet();
}
}).start();
try {
int lastCount = 0;
while (true) {
Thread.sleep(1000);
int thisCount = count.get();
System.out.printf("%s calls/sec%n", thisCount - lastCount);
lastCount = thisCount;
}
}
finally {
stop.set(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None possible.
FREQUENCY : often
- backported by
-
JDK-8253783 [linux] Runtime.availableProcessors execution time increased by factor of 100
- Resolved
-
JDK-8253983 [linux] Runtime.availableProcessors execution time increased by factor of 100
- Resolved
-
JDK-8254037 [linux] Runtime.availableProcessors execution time increased by factor of 100
- Resolved
-
JDK-8256947 [linux] Runtime.availableProcessors execution time increased by factor of 100
- Resolved
-
JDK-8257157 [linux] Runtime.availableProcessors execution time increased by factor of 100
- Resolved
-
JDK-8257283 [linux] Runtime.availableProcessors execution time increased by factor of 100
- Resolved
- relates to
-
JDK-8134851 Integrate CompletableFuture with API enhancements
- Resolved
-
JDK-8232207 Linux os::available_memory re-reads cgroup configuration on every invocation
- Resolved
-
JDK-8227018 CompletableFuture should not call Runtime.availableProcessors on fast path
- Resolved
-
JDK-8227019 CompletableFuture.waitingGet shouldn't call Runtime.availableProcessors in a tight loop
- Closed