【发布时间】:2014-07-10 23:59:01
【问题描述】:
我注意到,当我使用条件断点进行调试时,执行速度会大大减慢。我已经知道了一段时间,现在想了解原因。究竟发生了什么导致执行如此缓慢?我知道正在添加条件,但如果我自己添加条件,我不会减慢执行速度。
例如,假设我们有以下代码。假设我们添加了一个条件断点a=i。让我们将条件设置为 i==10000。
public class Main {
public static void main(String[] args) {
int a = 0;
for (int i = 0; i<100000; i++) {
a = i; //put breakpoint here (if i == 10000)
}
System.out.println("Done! a=" + a);
}
}
现在让我们自己编写条件。
public class Main {
public static void main(String[] args) {
int a = 0;
for (int i = 0; i<100000; i++) {
if (i == 10000)
a = i; //put a NON-conditional breakpoint here
else a = i;
}
System.out.println("Done! a=" + a);
}
}
为什么这两者的运行时间差别如此之大?为什么第一个这么慢?
如果您想知道,我在 Linux (Ubuntu) 上使用 Oracle-JDK-8。 我使用 Eclipse 和 IntelliJ 得到了相同的结果。
实验结果
我在多个 IDE 上运行了第一个案例,看看是否有区别。这是结果
智能:
~9 秒到达断点
~90 秒完成(包括最初的 9 秒)
日食:
~9 秒到达断点
~90 秒完成(包括最初的 9 秒)
Netbeans:
~ 12 秒到达断点
~ 190 秒完成(包括最初的 12 秒)
所以 IntelliJ 和 Eclipse 差不多,但 Netbeans 慢得多。
第二个示例几乎可以在所有 IDE 上立即运行,所以我没有做实验。 (但我确实将这三个都运行了,看看是否有任何延迟,没有一个。)
【问题讨论】:
-
虽然我不确定我会想象它与调试器如何接收和评估来自目标 JVM 的数据有关。我想它与 JConsole 和 VisualVM 使用 RMI 收集这些数据的方式非常相似。这与源代码中的条件绝对不属于同一级别,这使得它们很难比较,因为它们在做完全不同的事情。
-
您使用的是什么 IDE?可能是 IntelliJ 吗?
-
@AlexR 是 IntelliJ,但我在 eclipse 中遇到了同样的问题。
-
您使用什么工具进行调试?
-
我最好的猜测是一个非条件断点,调试器毫无疑问地停止代码,而在有条件的情况下,必须在决定停止或继续之前评估该条件。正如@MarkW 所说,获取数据需要一些时间,因为要评估条件,调试器会在断点处停止,获取数据并评估它。