了解 Java 调试如何真正在幕后工作

Posted

技术标签:

【中文标题】了解 Java 调试如何真正在幕后工作【英文标题】:Understanding how java debugging really works under the hood 【发布时间】:2014-04-30 22:01:22 【问题描述】:

我的问题与调试有关——尤其是在 java/jvm 上。

我想知道如何在 Java 中进行调试:

jdb/jvm如何将java源代码中设置的断点匹配到当前正在执行的字节码。

有人可以回答上述问题和/或指出与 jvm 调试相关的文档/规范及其工作原理吗?

【问题讨论】:

我在这里找到了另一个关于在 java 中调试的有趣帖子/答案:***.com/a/3591531/536299 以及官方文档:docs.oracle.com/javase/6/docs/technotes/guides/jpda/… 和 docs.oracle.com/javase/6/docs/technotes/guides/jpda 【参考方案1】:

查看 javac 文档: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html

特别是,默认情况下,javac 将在 .class 文件中存储原始源文件和行号,或者使用显式 -g 选项(及其派生项)。 Java 调试器将能够在运行时执行字节码时检索该信息,并将其与您的源代码相匹配。

这就是为什么,如果您的运行时类路径与源文件不同步(即“错误”的 jar / .class 文件位于运行时类路径中),调试器有时会显示错误的行号,甚至行似乎无法执行的数字。这是“坏”运行时类路径问题的典型特征(或者至少是您的源代码和编译代码之间的不一致)。

[已编辑] 从技术上讲,您可以通过使用 -g:none 来减小 .class/.jar 文件的大小,但实际上这通常是对磁盘空间的一种很好的利用,因为源代码/行号信息对于调试器以及 JVM 可能最终为您打印的堆栈跟踪都将变得非常方便。

【讨论】:

以上是关于了解 Java 调试如何真正在幕后工作的主要内容,如果未能解决你的问题,请参考以下文章

如何了解 jQuery 选择器在幕后的工作原理?

React 钩子 useRef() 如何在幕后工作?那个参考到底是啥?

如何使 GDB 与外部程序一起工作

IDEA Intellij 如何调试从 Java 类调用的 PL/SQL 代码

ORM 如何在幕后工作?另外,在 Java 中拥有持久对象的最佳方法是啥?

CUDA 分析如何“在幕后”工作?