长时间运行的方法会降低Java调试性能 [英] Slow Java Debugging Performance in Long-running Method

查看:123
本文介绍了长时间运行的方法会降低Java调试性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


更新:一年多以前我问这个问题时,仍然没有答案。出于好奇,我用IntelliJ IDEA重现了我今天在Eclipse中观察到的问题。

Update: While I asked this question over a year ago, there is still no answer. Out of curiosity, I reproduced the problem I observed with Eclipse today with IntelliJ IDEA.



问题



我最近正在调试一个类,该类包含执行许多操作的阻塞且长时间运行的方法。有趣的是,调试速度有时会发生很大的变化。我感觉速度与不同的调试方法(逐步进入,逐步执行,返回返回,恢复)相关。

Problem

I was recently debugging a class that contained a blocking and long-running method doing lots of operations. Interestingly the debugging speed varied extremely from time to time. I had a feeling that the speed correlated with the different debugging methods (Step Into, Step Over, Step Return, Resume).

我写了一个简单的例子,可以借助以下课程来重现和衡量我的感觉:

I wrote a minimal example and could reproduce and measure my feeling with the help of the following class:

测试类只是测量了计数器在长时间运行操作中递增。为了检验假设,我在调用 longRunningOperation 之前设置了一个断点以暂停程序,然后应用不同的调试方法。

The test class simply measures how often the counter is incremented in the "long running" operation. To test the hypothesis I set a breakpoint to halt the program before invoking the longRunningOperation and then applied the different debugging methods.

鉴于所示的断点,我以不同的调试策略以不特定的顺序执行了几次重复的测量(以最大程度地减少系统错误的可能性):

Given the shown breakpoint, I performed several repeated measurements in no particular order (to minimize chance of a systematic error) with different debugging strategies:


  1. 运行:只需执行程序(性能控制组)

  2. W / O Breakpoint :在调试模式下运行程序而无需断点

  3. 恢复:在断点处暂停,然后恢复执行(IntelliJ F9

  4. 结束:在断点处暂停,然后越过长期运行的方法(IntelliJ F8

  5. 进入+返回:在断点处停止,然后进入长期运行的方法并退出 (IntelliJ F7 ,然后按 SHIFT + F8

  6. Into + Resume :在断点处停止,然后进入长期运行的方法和简历(IntelliJ F7 ,然后是 F9

  1. Run: simply execute the program (performance control group)
  2. W/O Breakpoint: Runs the program in debug mode without a breakpoint
  3. Resume: Halt at the breakpoint, then resume the execution (IntelliJ F9)
  4. Over: Halt at the breakpoint, then step over the long running method (IntelliJ F8)
  5. Into+Return: Halt at the breakpoint, then step into the long running method and step out (IntelliJ F7, then SHIFT+F8)
  6. Into+Resume: Halt at the breakpoint, then step into the long running method and resume (IntelliJ F7, then F9)



实验结果



Experimental results


| #         | Run       | W/O Breakpoint | Resume    | Over     | Into+Return | Into+Resume |
|-----------|-----------|----------------|-----------|----------|-------------|-------------|
| 1         | 863342711 | 862587196      | 872204399 | 14722473 | 12550871    | 870687830   |
| 2         | 868929379 | 864245840      | 872166407 | 14139145 | 12487883    | 870626416   |
| 3         | 865544040 | 852645848      | 872988659 | 14352193 | 12459235    | 871062770   |
| 4         | 868100763 | 863198685      | 867518560 | 12261625 | 14696307    | 871365658   |
| 5         | 865157647 | 866257267      | 862671156 | 12524087 | 14620150    | 868541690   |
| 6         | 865348827 | 863449576      | 864416490 | 14410005 | 14592026    | 868784314   |
| 7         | 866957323 | 865379147      | 873324542 | 14326951 | 12648924    | 868621635   |
| 8         | 860129057 | 868993541      | 867785706 | 14434965 | 14380032    | 875011465   |
| 9         | 865961737 | 857872085      | 871137322 | 12440011 | 12262172    | 871357411   |
| 10        | 865517465 | 864911063      | 865109071 | 14544906 | 12391397    | 871574154   |
|           |           |                |           |          |             |             |
| Mean      | 865498895 | 862954025      | 868932231 | 13815636 | 13308900    | 870763334   |
| Deviation | 0,00%     | 0,29%          | -0,40%    | 98,40%   | 98,46%      | -0,61%      |

每个调试策略执行10次,结果为 System.out.println(res)显示在相应的列中。 平均值行包含每个策略的10个度量值的平均值。 Deviation 行包含与 Run 策略的相对偏差。结果是使用IntelliJ IDEA获得的,但在Eclipse中是相似的。

Each debugging strategy was executed 10 times and the result of System.out.println(res) is shown in the respective columns. The Mean row contains the mean value of the 10 measurements for each strategy. The Deviation row contains the relative deviation to the Run strategy. The results are obtained with IntelliJ IDEA, but are similar in Eclipse.

结果表明,使用与其他选项相比,跳过进入+退出在调试期间执行长时间运行的方法的速度比慢10倍。但是我无法解释为什么会这样?调试器在内部做了什么操作才能产生这种行为?

The results indicate that using step over or step into + step out to execute a long running method during debugging is more than 10x slower compared to the other options. However I cannot explain why this happens? What does the debugger internally do to yield such a behavior?

注意:我在Windows 10上使用Java 8和IntelliJ IDEA 2016.2执行了测量。

Note: I executed the measurements on Windows 10 with Java 8 and IntelliJ IDEA 2016.2.

为了在您的计算机上重现此行为,我将小型类放入了要点

To reproduce the behavior on your machine, I have put the small class into a Gist.

推荐答案

我仍然遇到同样的问题,我认为它的实现方式不像一般的Java调试(如果这是该实现方式的错误,IntelliJ必须同样严重地实现它,并且两个IDE都很难实现它,对我而言似乎不太可能)

I am still experiencing the same problem and I believe it is not so much the implementation as Java debugging in general (If it was the implementation's fault IntelliJ had to implement it equally badly and that both IDEs implement it that badly seems rather unlikely to me).

我发现这篇关于SO的帖子导致我怀疑,在单步执行代码时,Java不会一步步离开未优化的解释字节码。当我继续时,我相信它会检查它可以运行到什么时候,并以优化的方法运行,从而使这一过程变得更快。

但是请注意,这只是我个人的怀疑,我确实没有任何事实可以证明这一点(除了这些操作的执行情况)。

I found this post here on SO that led me to the suspicion that when stepping over code, Java never leaves the unoptimized interpret bytecode step by step. When continuing I believe it checks until which point it may run and does so in the optimized approach, making this a hell lot faster.
Note however that this is only my personal suspicion and that I do not have any facts that would proof this (other than the performance of those operations).

但是我确实找到了解决此问题的方法。即:运行到行

此功能将代码运行到当前光标所在的行。因此,它似乎与向该行添加断点,继续执行并再次删除该断点具有相同的效果。通过这种方法,可以通过将光标置于下一行并单击 Ctrl + R (此操作的默认快捷方式)来跳过一行。

I did however find a "solution" to this problem. Namely: Run to Line.
This feature will run the code up to the line in which your cursor is currently placed. Therefore it seems to have the very same effect as adding a breakpoint to the line, continuing the execution and then removing the breakpoint again. With this approach one can "step over" a line by placing the cursor on the next line and hitting Ctrl+R (default shortcut for this).

这篇关于长时间运行的方法会降低Java调试性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆