为什么Java代码在调试器中会变慢?

时间:2010-02-03 21:47:52

标签: java debugging jboss intellij-idea

通过调试器运行时,某些CPU密集型例程会显着变慢。为什么是这样?

目前我只是使用IntelliJ来逐步运行在JBoss中运行的代码。当我启动JBoss时,我使用以下选项:

set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MaxPermSize=256m -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n %JAVA_OPTS%

有没有办法加快执行速度?或者加快我不需要介入的某些方法执行?


更新:似乎我没有跨越/进入CPU密集型例程(即:只运行直到在例程之后设置的断点),然后执行时间就好像不在调试器。

7 个答案:

答案 0 :(得分:42)

  

通过调试器运行时,某些CPU密集型例程会显着变慢。这是为什么?

因为在启用调试时,JITter不会对代码进行尽可能多的优化(通常,根本不会)。

答案 1 :(得分:7)

它还取决于“断点式”。例如。在变量上设置观察点或在接口级别上设置断点(调试器在执行时将停止在所有方法实现上)通常会大大减慢处理时间。

答案 2 :(得分:5)

调试时,除运行应用程序外,还运行调试器。

代码在调试模式中编译,包含有关局部变量和其他源级信息的元数据符号。调试器读取以知道哪一行源代码与当前指令相对应。该过程称为符号调试。存储的符号会增加代码大小并解释它们会增加执行时间。

有些调试器实际上会动态解释代码,这几乎总是一个主要的性能损失。

有关Java调试编译模式的更多信息,由javac执行,包括类文件中的调试信息Java Language Compiler Options。 例如:-g生成所有调试信息,包括局部变量。

答案 3 :(得分:2)

你需要考虑另一个程序 - 调试器 - 挂钩到你的程序中,并且正在观察异常之类的事情。它还监视当前行,以便对断点或用户请求的中断作出反应(如暂停请求或监视条件)。

答案 4 :(得分:1)

调试JIT生成的优化代码会非常困难,因为一系列本机指令和一行Java代码之间没有直接关系,就像一系列Java字节码和一行之间存在关系Java代码。

因此,在调试器中进入函数会强制JVM取消优化您正在逐步执行的方法。 Hotspot根本不生成本机代码,只是解释方法的字节码。

在JDK 1.4.1开始启用调试之前,强制JVM只使用解释器:http://java.sun.com/products/hotspot/docs/whitepaper/Java_Hotspot_v1.4.1/Java_HSpot_WP_v1.4.1_1002_3.html#full

答案 5 :(得分:0)

顶级提示:在IDEA中,您可以使用ALT + F9运行到放置光标的位置,而不是设置额外的断点。

我发现有趣的是,如果您正在遍历可从堆栈访问的大量数据的代码,则在IDEA中调试变得非常慢。不要忘记,IDEA收集这些数据(当前在词汇范围内的任何内容)并将其作为一个对象树呈现给您,以便浏览您是否“观察”,并在每个后续步骤中执行此操作(也许每次都重新创建树?)。

例如,当一个大集合作为“当前”对象的实例变量时,这一点尤为明显。

答案 6 :(得分:-1)

如果使用Java 5,则调试参数为:

-agentlib:JDWP =运输= dt_socket,服务器= Y,暂停= n时,地址=

之前和Java 5之前

-Xdebug -Xrunjdwp:transport = dt_socket,address = 5005,server = y,suspend = n