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

通过调试器运行时,一些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密集型例程(即:只运行直到例程后设置的断点),然后执行时间好像不在调试器中。

通过调试器运行时,一些CPU密集型例程会变得非常慢。 为什么是这样?

因为启用调试时,JITter不会优化代码(通常,根本不会)。

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

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

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

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

有关Java调试编译模式的更多信息,该模式由javac执行,并在类文件中包含调试信息 : Java语言编译器选项 。 例如: -g生成所有调试信息,包括局部变量。

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

调试由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

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

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

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

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

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

在Java 5之前

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