有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么启用某些异常的调试要慢得多?

考虑以下代码:

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) 个答案

  1. # 1 楼答案

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

    UnsupportedOperationException在程序的生命周期中从不加载。这就是为什么程序运行速度和没有断点时一样快

    IllegalArgumentException是一个非常流行的类,它在JVM启动期间加载到JDK类库中的某个地方。在这种情况下,确实设置了异常断点,以便调试器接收有关程序中抛出的所有异常的通知