在调试模式下运行JVM的副作用

25

我想以调试模式发布Java应用程序,以便在客户端出现难以复现的问题时更容易进行调试。

但是我想提前了解这样做可能带来的潜在副作用。从Java HotSpot文档中得知,似乎没有性能损失。

根据该链接内容:

全速调试

Java HotSpot VM 现在使用全速调试。在 VM 的早期版本中,在启用调试时,程序仅使用解释器执行。现在,即使是编译代码,程序也可以获得 HotSpot 技术的全部性能优势。这种改进后的性能让长时间运行的程序更容易调试,同时允许测试以全速进行。一旦出现异常,调试器将使用完整的代码源进行调试。

这是否准确无误?还是存在隐藏的注意事项?内存占用情况如何?在使用调试模式时是否存在其他隐藏的陷阱?

提示:我发现这篇文章来自 AMD,证实了我最初的怀疑,即 oricale 的原始文章没有透露全部情况。


你在Java HotSpot网站上读到了什么内容,让你得出了不会有性能惩罚的结论? - linuxuser27
全速调试Java HotSpot VM 现在采用全速调试。在 VM 的先前版本中,启用调试时,程序仅使用解释器执行。现在,即使是经过编译的代码,HotSpot 技术的全部性能优势也可用于程序。改进后的性能使得长时间运行的程序更容易进行调试。它还允许测试以全速继续进行。一旦出现异常,调试器会启动并对代码源具有完全的可见性。 - hhafez
AMD的文章消失了。 :( - Simon Forsberg
4个回答

16

我不能代表HotSpot或IBM官方发言,但我可以说,有一些法律允许的优化方式在反编译时是无法完全撤销的,因此当您要求在生产JVM中启用调试功能时,这些优化方式不会被启用。

想象一种情况,优化器发现程序的某个部分可以被证明是不需要的,并且根据各种语言规则(包括JSR 133)可以合法地删除,JVM会希望将其删除。唯一的问题是调试:删除代码在人工步进时会看起来很奇怪(变量不更新,可能在步进时不停留在行上),因此选择在这些情况下禁用该优化。对于像栈分配对象等优化选项也可能适用同样的情况。因此,尽管JVM声称它是“满速运行”,但实际上更接近于“几乎满速运行,并取消了某些无法完全恢复的奇特优化”。


1
你可以在非调试模式下强制禁用优化,或者在调试模式下强制启用优化,以便两种模式具有相同的行为吗? - hhafez
抱歉,我不知道HotSpot的答案。从我在J9中看到的情况来看,没有受支持的方法来禁用某些选项(或者具体清单是什么)。不,你不能在调试模式下启用不安全的选项 - 当遇到非法状态时,JVM会直接崩溃,我们不想要那样的结果!<g> - Trent Gray-Donald

6

这个问题虽然有些陈旧,但是在我搜索是否会存在性能影响的时候出现了:如果您只是开启了 -agentlib:jdwp... 而没有进行调试,会不会对性能有影响。

总结:从调试选项开始,但不连接并不会影响速度(Java 7+)。

在 Java 6 之前,您使用的是 -Xdebug,它肯定会产生影响,因为它关闭了 JIT!

在 Java 6 中,他们将其更改为 -agentlib 并使其变得更好。但是还存在一些导致性能下降的 bug。以下是针对 OpenJDK 提交的一个 bug,我的猜测是 Oracle/Sun 版本也存在类似的问题:https://bugs.openjdk.java.net/browse/JDK-6902182

请注意,陈述的目标是仅通过打开端口启用调试不应造成任何性能损失。

看起来,在 OpenJDK 中至少到 Java 7 时,已经修复了这些 bug。在那之后,我没有看到任何关于性能影响的内容。

如果您进一步研究并发现了负面结果,请注意测试所执行的 Java 版本-我所看到的所有内容都是指 7 之前的版本。

如果有人在最近的 VM 中只是开启了端口而遇到性能问题,我很想听听。


4

如果您计划启用远程调试运行应用程序,这也会影响安全性。远程调试会在您的机器上打开一个端口,通过连接到该端口,我可以对您的应用程序进行各种有趣的操作。


如果你进行远程调试,那么这是正确的,但如果没有进行远程调试,则不是这种情况。 - hhafez
1
@hhafez 是的,这就是为什么我写了“如果您计划启用远程调试运行应用程序”的原因 :) - Hila

1
程序在调试模式下肯定不仅仅是运行,因此性能显然不能相同。但是如果您仔细阅读该声明,它表明新版本可以在调试模式下运行完全优化的代码,而以前是不可能的。因此,新的 JVM 比以前的更快,以前的 JVM 只能在解释模式下运行,没有优化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接