JDK-6888526 : Linux getCurrentThreadCpuTime is drastically slower than Windows
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: 6u16
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2009-10-06
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u21pFixed 7Fixed hs19Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_07" (hotspot client VM)
1.6.0u16, for Linux.

ADDITIONAL OS VERSION INFORMATION :
Linux kernel 2.6.18/Ubuntu 8.04

A DESCRIPTION OF THE PROBLEM :
The getCurrentThreadCpuTime method is extremely slow on Linux, due to its use of /proc entry for getting thread CPU timing information.

  To wit, the submitted test case takes almost 4 seconds to do 100k CPU measurements, where as the IBM Linux JDK takes only 144 ms (25x faster) on the same machine.

Specifically, upon reviewing the source code for JDK 1.6u7, it appears that while there is an implementation of fast Posix based CPU timing measurement, it is disabled in hotspot\src\os\linux\vm\globals_linux.hpp (UseLinuxPosixThreadCPUClocks is defined to be false).

The constant is defined the same way in JDK 1.6u18 and August version of JDK 1.7, so this problem persists even in those later versions.

A fix would appears to be as simple as defining the UseLinuxPosixThreadCPUClocks to be true, so that the fast CPU time measurement implementation can be turned on.

I have downloaded and tested the bug against the latest version of JRE, 1.6.0u16, for Linux.

The bug still exists and the performance is still just as slow. The IBM JVM continues to be 25x faster than the Sun Java 6 update 16 JVM on the same hardware.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Please run submitted test code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
  Took: 144 ms.
(as run and recorded on IBM Linux JDK)
ACTUAL -
  Took: 3700 ms.
(as run and recorded on Sun JDK on the same machine; about 25x slower)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public static void main(String[] args) {
  long base = cputime();

  for(int k = 0; k < 100 * 1000; k++) {
          cputime();
  }

  System.out.println("Took: " + ((cputime() - base) / 1000.0 / 1000.0) + " ms.");
}

private final static long cputime() {
    return java.lang.management.ManagementFactory.getThreadMXBean()
    .getCurrentThreadCpuTime();
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The Oracle/BEA JRockit JVM and Sun JVM on Linux both exhibit this problem. The only workaround is to run the Windows version of the Sun JDK, or switch to the IBM version of JDK on Linux, which does not have this problem.

Comments
EVALUATION The changeset in the previous entry was targeted for JDK7-B106, but the HSX-19-B06 integration into JDK7-B106 did not happen as planned. This changeset is now targeted for JDK7-B107.
24-08-2010

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/3d90023429ec
02-08-2010

EVALUATION This bug was fixed by Andrew Haley at RedHat using the following changeset: Changeset: 3d90023429ec Author: aph Date: 2010-07-28 17:38 +0100 URL: http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/rev/3d90023429ec 6888526: Linux getCurrentThreadCpuTime is drastically slower than Windows Reviewed-by: dcubed, dholmes ! src/os/linux/vm/globals_linux.hpp ! src/share/vm/runtime/arguments.cpp
02-08-2010

EVALUATION It seems reasonable to turn on this flag by default for Java 7, however we need to retain the present setting in Java 6.
08-07-2010

WORK AROUND Use -XX:+UseLinuxPosixThreadCPUClocks or export JAVA_TOOL_OPTIONS=-XX:+UseLinuxPosixThreadCPUClocks
06-10-2009

EVALUATION As the submitter notes the functionality exists but is disabled by default. The user can easily enable it by specifying -XX:+UseLinuxPosixThreadCPUClocks The functionality was added for JDK 6 under CR 6200022 but there was concern at the time about enabling it by default (those concerns are not documented in 6200022). Perhaps it is time to enable this feature by default?
06-10-2009