Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-3498

Significant performance degradation after step over during debugging

Linking RHIVOS CVEs to...Migration: Automation ...Sync from "Extern...XMLWordPrintable

    • None
    • None
    • Customer Escalated
    • rhel-sst-java
    • None
    • False
    • False
    • Hide

      None

      Show
      None
    • None
    • None
    • None
    • None
    • If docs needed, set a value
    • None
    • 57,005

      Description of problem:

      We observe significant performance degradation if step over is used while debugging. We found this problem with Eclipse and Java 11 / Java 17, but its reproducible also with jdb and Java 11 / Java 17.

      Version-Release number of selected component (if applicable):

      OpenJDK 11.0.10 (seen also with latest master compiled from https://github.com/openjdk/jdk11u)
      OpenJDK 17.0.4

      How reproducible:

      Debug the following snippet:

      public class StepOver {
      public static void main(String[] args) throws Exception {
      System.out.println(); // set a breakpoint here, and step over
      System.out.println(); // press Resume when suspended here
      double[] ySeries = new double[100_000];
      for (int i = 0; i < ySeries.length; i++)

      { ySeries[i] = Math.sin(i / 20) * Math.pow(10, -21); }

      long startTime = System.currentTimeMillis();
      for (int i = 0; i < ySeries.length; i++)

      { String.valueOf(ySeries[i]); }

      System.out.println("elapsed time: " + (System.currentTimeMillis() - startTime));
      }
      }

      Steps to Reproduce:
      1. Compile
      /usr/lib/jvm/java-17/bin/javac StepOver.java

      2. Debug the following snippet with jdb
      /usr/lib/jvm/java-17/bin/jdb StepOver

      3. Set a breakpoint at StepOver:3
      stop at StepOver:3

      4. Run the snippet
      run StepOver

      5. Step over the breakpoint:
      step over

      6. Continue execution:
      cont

      Actual results:

      Observe the snippet takes 8+ seconds to finish (HP Z640 workstation).

      Expected results:

      The snippet doesn't take much longer to finish than without stepping over during debugging.

      Additional info:

      The bug was introduced with this commit: https://github.com/openjdk/jdk11u/commit/dbb9eb5b9c3ddcbcfaae8ac4ca21760c9c99a15c

      Specifically this change "fixes" the performance downgrade:

      diff --git a/src/hotspot/share/prims/jvmtiEventController.cpp b/src/hotspot/share/prims/jvmtiEventController.cpp
      index 38de6383cc..22d0f40c97 100644
      — a/src/hotspot/share/prims/jvmtiEventController.cpp
      +++ b/src/hotspot/share/prims/jvmtiEventController.cpp
      @@ -523,7 +523,7 @@ JvmtiEventControllerPrivate::recompute_thread_enabled(JvmtiThreadState *state) {
      JvmtiEnvThreadStateIterator it(state);
      for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets))

      { any_env_enabled |= recompute_env_thread_enabled(ets, state); - has_frame_pops |= ets->has_frame_pops(); + //has_frame_pops |= ets->has_frame_pops(); }

      }

      In particular, the interpreter only mode is entered after step over and is never left after this change. Whereas before the change, the interpreter only mode is left after the step over handling is done.

      Note that execution directly after this change takes 27+ seconds. There is another change that seems to help with the performance (bringing it down to 8+ seconds):

      https://github.com/openjdk/jdk11u/commit/e221522f106318175cfc6f9b38542670656a4cd8

      Output with Java 17, using jdb with step over:

      $ /usr/lib/jvm/java-11/bin/jdb StepOver
      Initializing jdb ...
      > stop at StepOver:3
      Deferring breakpoint StepOver:3.
      It will be set after the class is loaded.
      > run StepOver
      run StepOver
      Set uncaught java.lang.Throwable
      Set deferred uncaught java.lang.Throwable
      >
      VM Started: Set deferred breakpoint StepOver:3

      Breakpoint hit: "thread=main", StepOver.main(), line=3 bci=0
      3 System.out.println(); // set a breakpoint here, and step over

      main[1] list
      1 public class StepOver {
      2 public static void main(String[] args) throws Exception {
      3 => System.out.println(); // set a breakpoint here, and step over
      4 System.out.println(); // press Resume when suspended here
      5 double[] ySeries = new double[100_000];
      6 for (int i = 0; i < ySeries.length; i++)

      { 7 ySeries[i] = Math.sin(i / 20) * Math.pow(10, -21); 8 }
      9 long startTime = System.currentTimeMillis();
      10 for (int i = 0; i < ySeries.length; i++) {
      main[1] step over
      >
      Step completed: "thread=main", jdk.internal.misc.Unsafe.arrayBaseOffset(), line=1,056 bci=1

      main[1] cont
      >

      elapsed time: 8241

      The application exited


      Output with Java 17, without using step over:

      $ /usr/lib/jvm/java-11/bin/jdb StepOver
      Initializing jdb ...
      > stop at StepOver:3
      Deferring breakpoint StepOver:3.
      It will be set after the class is loaded.
      > run StepOver
      run StepOver
      Set uncaught java.lang.Throwable
      Set deferred uncaught java.lang.Throwable
      >
      VM Started: Set deferred breakpoint StepOver:3

      Breakpoint hit: "thread=main", StepOver.main(), line=3 bci=0
      3 System.out.println(); // set a breakpoint here, and step over

      main[1] list
      1 public class StepOver {
      2 public static void main(String[] args) throws Exception {
      3 => System.out.println(); // set a breakpoint here, and step over
      4 System.out.println(); // press Resume when suspended here
      5 double[] ySeries = new double[100_000];
      6 for (int i = 0; i < ySeries.length; i++) {7 ySeries[i] = Math.sin(i / 20) * Math.pow(10, -21);8 }

      9 long startTime = System.currentTimeMillis();
      10 for (int i = 0; i < ySeries.length; i++) {
      main[1] cont
      >

      elapsed time: 133

      The application exited

      The output and execution time are essentially the same with Java 17.

              rhn-engineering-adinn Andrew Dinn
              jira-bugzilla-migration RH Bugzilla Integration
              Andrew Hughes Andrew Hughes
              David Kutalek David Kutalek
              Votes:
              2 Vote for this issue
              Watchers:
              12 Start watching this issue

                Created:
                Updated:
                Resolved: