Java-Launcher类上打断点无效的案例解读
这是一个有意思的案例~?首先,以下是一个广为流传的说法:
?内建于 JVM 中的启动类加载器(Bootstrap Class Loader)会加载 java.lang.ClassLoder 以及其他 Java 平台类,Launcher 类由此被启动类加载器加载和初始化,因为 Launcer 的静态代码会产生一个 Luancher 实例,继而又会产生了一对 Extension Class Loader 和 Application Class Loader 实例。
?其中,“从加载乃至初始化 Launcher 类,会有创建一个 Launcher 实例,那么又便会创建 Extension Class Loader 和 Application Class Loader 实例”这个观点从 sun.misc.Launcher 类的源码很容易得到验证。问题是如何证明启动类加载器会主动加载以及导致 Launcher 类的初始化呢?很容易想到,在 Launcher 的构造器内部打一个断点不就完事了。
?一般地,debug 的确是解决这类问题的好方法,但是偏偏这个案例中你在 Launcher 的构造器内部打上的断点会被跳过。
?于是,为了验证断点的有效性,在程序中主动调用了 Launcher 类的构造器,如下:
Launcher launcher = new Launcher();
?在断点不变的情况下,debug 模式下成功暂停了。
?这难道证明了广为流传的说法是错误的?
?于是我去翻看了 OpenJDK 对于 Launcher 类的描述:This class is used by the system to launch the main application.
?system 讲道理就是 JVM 的意思,所以广为流传的说法是对的,那么问题会不会是 debug 机制的问题?
?于是我又翻了翻 IBM 关于 Java 中 Debug 实现原理的介绍,文章地址如下:
【Java-Launcher类上打断点无效的案例解读】?https://www.ibm.com/developerworks/cn/java/j-lo-jpda1/
?文章中说到:JDI(Java Debug Interface)是三个模块中最高层的接口,在多数的 JDK 中,它是由 Java 语言实现的。
?参考 Oracle 的官方文档:https://docs.oracle.com/javase/9/docs/api/jdk.jdi-summary.html
?可以知道
jdi
是一个位于 tools.jar 包下的子包,而 tools.jar 也是由 BootStrap 类加载器负责加载的。?所以现在我们可以知道了,为 Java 提供 Debug 支持的类加载和 Launcher 的类加载都是由 Bootstrap 类加载器负责的,只是后者先发生,所以 debug 功能实现的时候,Launcher 的构造器早已运行结束了。
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)