为什么 Java 代码在调试器中变慢?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2195720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does Java code slow down in debugger?
提问by Marcus Leon
Some CPU intensive routines get dramatically slower when run through a debugger. Why is this?
当通过调试器运行时,一些 CPU 密集型例程会显着变慢。为什么是这样?
Currently I'm just using IntelliJ to step through code running in JBoss. When I start JBoss, I use these options:
目前我只是使用 IntelliJ 来逐步执行在 JBoss 中运行的代码。当我启动 JBoss 时,我使用以下选项:
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MaxPermSize=256m -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n %JAVA_OPTS%
Is there a way to speed up the execution? Or to speed up certain method executions that I don't need to step through?
有没有办法加快执行速度?或者加速某些我不需要单步执行的方法?
Update: Seems if I don't step over/into the CPU intensive routines (ie: Just run til a breakpoint set right after the routine), then the execution time is as if not in a debugger.
更新:似乎如果我没有跳过/进入 CPU 密集型例程(即:只运行直到在例程之后设置断点),那么执行时间就好像不在调试器中一样。
回答by Anon.
Some CPU intensive routines get dramatically slower when run through a debugger. Why is this?
当通过调试器运行时,一些 CPU 密集型例程会显着变慢。为什么是这样?
Because the JITter won't optimize code as much (often, not at all) when debugging is enabled.
因为在启用调试时,JITter 不会优化代码那么多(通常,根本不会)。
回答by manuel aldana
It also depends on the "breakpoints-style". E.g. having watchpoints on variables or putting breakpoints on interface level (debugger will stop on all method-implementations when they're executed) often dramatically slows down the process time.
它还取决于“断点式”。例如,在变量上设置观察点或在接口级别设置断点(调试器将在所有方法实现执行时停止)通常会显着减慢处理时间。
回答by Abboq
When debugging, in addition to running your application, you are also running a debugger.
调试时,除了运行您的应用程序,您还运行调试器。
The code is compiled in debug modewith metadata symbols about local variables and other source-level information. The debugger reads to know which line of source code corresponds with the current instruction. The process is called symbolic debugging. The stored symbols increase code size and interpreting them increases execution time.
代码在调试模式下编译,带有关于局部变量和其他源级信息的元数据符号。调试器读取以了解哪一行源代码对应于当前指令。该过程称为符号调试。存储的符号会增加代码大小,解释它们会增加执行时间。
Some debuggers actually interpret the code on the fly, which is almost always a major performance hit.
一些调试器实际上是在运行中解释代码,这几乎总是一个主要的性能损失。
More information about Java's debug compilation mode, which is performed by javacand includes debug information in class files: Java Language Compiler Options.
For example: -ggenerates all debugging information, including local variables.
有关 Java 调试编译模式的更多信息,该模式由类文件执行javac并包含调试信息:Java 语言编译器选项。例如:-g生成所有调试信息,包括局部变量。
回答by Frank V
You do need to consider that another program -- the debugger -- is hookedinto your program and is watching it for things like exceptions. It's also monitoring the current line in order to react to breakpoints or user requested interruptions (like a pause request or watch condition).
您确实需要考虑另一个程序——调试器——已挂接到您的程序中,并正在监视它是否有异常等情况。它还监视当前行,以便对断点或用户请求的中断(如暂停请求或监视条件)做出反应。
回答by Dan Berindei
Debugging the optimized code produced by the JIT would be very hard, because there isn't a direct relationship between a range of native instructions and a line of Java code like there is a relationship between a range of Java bytecode and a line of Java code.
调试由 JIT 生成的优化代码将非常困难,因为一系列本机指令和一行 Java 代码之间没有直接关系,就像一系列 Java 字节码和一行 Java 代码之间存在关系一样.
So breaking into a function in the debugger forces the JVM to deoptimize the method you are stepping through. Hotspot doesn't generate native code at all and just interprets the bytecode of the method.
因此,进入调试器中的某个函数会强制 JVM 对您正在逐步执行的方法进行反优化。Hotspot 根本不生成本机代码,只是解释方法的字节码。
Prior to JDK 1.4.1 starting with debugging enabled forced the JVM to only use the interpreter: http://java.sun.com/products/hotspot/docs/whitepaper/Java_Hotspot_v1.4.1/Java_HSpot_WP_v1.4.1_1002_3.html#full
在启用调试的 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
回答by oxbow_lakes
Top Tip: in IDEA you can use ALT+F9 to run to where you have the cursor placed rather than set an extra breakpoint.
重要提示:在 IDEA 中,您可以使用 ALT+F9 运行到光标所在的位置,而不是设置额外的断点。
I have found anecdotally that debugging becomes veryslow in IDEA if you are walking through code where there is a lot of data accessible from the stack. Don't forget, IDEA collects this data (anything currently in the lexical scope) and presents it up to you as a tree of objects to browse whether you are "watching" or not and does this at every subsequent step(maybe it re-creates the tree each time?).
我发现在 IDEA中调试会变得非常缓慢,如果您正在浏览可以从堆栈访问大量数据的代码。不要忘记,IDEA 收集这些数据(当前在词法范围内的任何数据)并将其作为对象树呈现给您,以浏览您是否在“观看”或不“观看”,并在每个后续步骤中执行此操作(也许它重新每次都创建树?)。
This is especially apparent when, for example, there is a large collection as an instance variable of the "current" object.
例如,当有一个大集合作为“当前”对象的实例变量时,这一点尤其明显。
回答by Marco Semiao
If you use Java 5, the parameter for debugging is :
如果你使用Java 5,调试的参数是:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=
and before Java 5
在 Java 5 之前
-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n
-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n

