为什么启用某些例外的调试要慢得多?

时间:2018-08-02 12:21:10

标签: java scala debugging intellij-idea jvm

考虑以下代码:

public class JMain {
    private final static int forLength = 6;

    private static void returnFromFor(int breakAt) {
        try {
            for (int j = 0; j < forLength; j++) {
                if (j == breakAt) {
                    throw new Throwable("break");
                }
            }
        } catch (Throwable ignored) {
        }
    }

    public static void main(String args[]) {
        long start = System.currentTimeMillis();
        int iterations = 100000;
        for (int i = 0; i < iterations; i++) {
            returnFromFor(i % forLength);
        }

        long end = System.currentTimeMillis();
        System.out.println(((Long) (end - start)).toString() + " ms");
    }
}

当我在IntelliJ IDEA调试器中运行此代码并为java.lang.IllegalArgumentException启用了异常断点时,它在我的计算机上运行的非常慢,大约1800毫秒。当我在无异常断点的情况下运行它或为java.lang.UnsupportedOperationException启用断点时,它的运行速度快大约10倍。

我的问题是:

  • 为什么使用IllegalArgumentException进行调试要比使用UnsupportedOperationException进行调试慢得多?

  • 是由JVM调试器还是由IntelliJ引起的速度下降?

我在其上运行的系统是:

  • Windows x64
  • IntelliJ IDEA Ultimate 2018.2
  • JRE:1.8.0_152-release-1248-b8 amd64

注意:上面的代码演示了我在使用复杂的Scala时遇到的问题。如果有人对更自然的Scala代码演示感兴趣,那么它来了:

object Main extends App {

  val forLength = 6
  def returnFromFor(breakAt: Int): Unit = {
    for (j <- 0 until forLength) {
      if (j == breakAt) return
    }
  }

  val start = System.currentTimeMillis()
  val iterations = 100000
  for (i <- 0 until iterations) {
    returnFromFor(i%forLength)
  }
  val end = System.currentTimeMillis()
  println(s"Duration ${end-start} ms")

}

1 个答案:

答案 0 :(得分:4)

在加载目标异常类之前,IDEA不会设置异常断点。

UnsupportedOperationException从未在程序的生命周期内加载。这就是为什么该程序以完全没有断点的速度运行的原因。

IllegalArgumentException是更受欢迎的类,它在JVM启动期间加载到JDK类库中的某个位置。在这种情况下,确实设置了异常断点,以便调试器接收有关程序中引发的所有异常的通知。

相关问题