Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8046511

Performance regression with Java 8 when application exits

XMLWordPrintable

    • x86_64
    • linux

      FULL PRODUCT VERSION :
      java version "1.8.0_05"
      Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)


      FULL OS VERSION :
      Linux 3.13-1-amd64 #1 SMP Debian 3.13.10-1 (2014-04-15) x86_64 GNU/Linux, Windows, Mac OS

      A DESCRIPTION OF THE PROBLEM :
      When running with Java 8 there are cases where it takes 1.5s or more between call to System.exit(int) and real end of process. This is a huge performance regression for calls to Java applications that take several seconds on all previous Java versions (tests Java 5-7). We see this with a command line invocations of Gradle (http://gradle.org/) that are typical when investigating how to run the build - 'gradle help' or gradle tasks'. Some facts:

      1. It doesn’t happen on older JVMs
      2. It happens on all major platforms (OS X, Linux, Windows).
      3. It happens when running `gradle help`
      4. It doesn’t happen when running `gradle -v` or `gradle —daemon help`.
      5. It doesn’t happen for an empty build script.
      6. It happens for a simple build script: apply plugin: ‘java’
      7. It happens for older Gradle versions (1.11 and 1.12 and 1.0).

      Because the delay happens after System.exit(int) is called we couldn't find any reasonable information using JVMTI based profilers. The best what we found were 'jstack -m' outputs showing activity in Hotspot compiler threads after JVM enters safepoint exit (-XX:+TraceSafepoint when running with fastdebug build shows 'Entering safepoint region: Exit' followed by that extra activity). This sounds like plausible explanation given that
      - very simple runs are not affected (with an empty build script) because they load limited number of classes
      - the problem is often seen when groovy runtime is loaded possibly with groovyc to compile build script (Gradle uses Groovy based DSL). This is done quickly after startup and probably buffers too many requests into compiler
      - longer builds do not suffer so heavily as there are not many compilation requests towards the end of JVM run.
      - using -Xint make the problem go away (while the total time is increased but comparable between major Java releases)


      THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

      THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

      REGRESSION. Last worked in version 7u60

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      wget https://services.gradle.org/distributions/gradle-1.12-all.zip
      unzip gradle-1.12-all.zip
      mkdir demo
      cd demo
      echo "apply plugin: 'java'" >>build.gradle
      time ../gradle-1.12/bin/gradle --no-daemon help

      repeat the last command with Java 7 and 8 on your PATH to see the difference

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Running with Java 8 shows time computed in Java code as 'Total time: 3.615 secs'
      while 'time's output is
      real 0m8.570s
      user 0m17.796s
      sys 0m0.200s
      where almost complete difference is at the end of JVM run.

      Running with Java 7 shows
      Total time: 2.215 secs

      real 0m2.921s
      user 0m5.392s
      sys 0m0.088s

      where the overhead on JVM run is minimal.

      REPRODUCIBILITY :
      This bug can be reproduced always.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: