4.4 实战:在Launcher中添加自定义函数模块当大家理解 Launcher 的执行过程后,便可以开始着手尝试在 Launcher 的源码中添加一些自定义的函数模块。因为这样一来,当你在实际的开发过程中需要通过修改 HotSpot 的源码满足特定的业务场景时,自然会有所帮助,毕竟勇于迈出第一步是非常重要的。在本章的实战小节中,我们要做的仅仅只是在 Launcher 调用 CallStaticVoidMethod()函数执行之前,在自定义函数中引用传递给 CallStaticVoidMethod()函数的一些变量参数。如下所示:代码 4-21 添加 setParameters()函数 /* 在调用 CallStaticVoidMethod()函数之前,引用其变量参数 */ setParameters(env, mainClass, mainID, mainArgs); /* 执行 Java 程序的 main()方法 */ (*env)-CallStaticVoidMethod(env, mainClass, mainID, mainArgs);上 述 语 句 中 , 笔 者 在 CallStaticVoidMethod() 函 数 执 行 之 前 调 用 了 自 定 义 函 数setParameters() 引 用 了 传 递 给 CallStaticVoidMethod() 函 数 的 一 些 变 量 参 数 。 其 实setParameters()函数中所包含的功能只是引用了这些传递过来的变量参数,并输出一串字符信息而已。如下所示:代码 4-22 自定义 setParameters()函数 /* * 引用变量参数信息 */ void getParameters(jstring mainClassName,JNIEnv *env,jclass mainClass, jmethodID mainID, jobjectArray mainArgs){ printf("成功接收到变量参数..."); }成功将 Launcher 的源码重新编译后,大家便可以使用 GDB 工具调试上述这段代码。当程序执行到 setParameters()函数时,输入命令“ step”将会进入到该函数的内部;再次输入命令“ info args”后,便会输出 setParameters()函数引用的这些变量的参数值,如下所示:(gdb) info args mainClassName = 0xb680a5dc env = 0xb6809148 mainClass = 0xb680a5e0 mainID = 0xb6858990 mainArgs = 0xb680a5f0本书 1.5.2 节中介绍了基于 OpenJDK 深度定制的 TaobaoVM,在此笔者不得不佩服和认同淘宝的技术实力。淘宝的技术团队敢于做国内第一个吃螃蟹的人,不仅深入到 HotSpot的源码底层修改大量的实现细节,更是在原有基础之上扩充了适应自身业务特点的一些新特性。单从这两点来看,淘宝做得确实非常不错。如果大家同样对此感兴趣,也可以尝试着往更深层次的方面修改 HotSpot 的源码或者扩充新的功能实现,这样不仅可以帮助你更好地理解 HotSpot,还能让你在 JVM 领域拥有更深的造诣。4.5 本章小结本章笔者深入源码剖析了 Launcher 的实现细节和执行过程,其中涵盖了 Launcher 中用于创建运行环境的启动函数 main()、主线程函数 JavaMain()、初始化 JVM 的 InitializeJVM()函数、获取 Java 程序启动类的 LoadClass()函数、获取 Java 启动方法的 getStaticMethodId()函数 、 调 用 Java 程 序 main() 方 法的 CallStaticVoidMethod() 函 数、 断开 主线程 连接 的DetachCurrentThread()函数和销毁 JVM 的 DestroyJavaVM()函数。当大家理解了本章每节所阐述的内容后,再亲自动手使用 GDB 或者其他 IDE 工具进行调试跟踪,相信这会对你在后续章节的学习中有所帮助。第5章剖析HotSpot的初始化过程之前笔者在第 4 章中曾经提及过,由 Launcher 负责调用 HotSpot 的核心代码对 JVM 执行初始化,以及由它负责维护 JVM 的整个生命周期。那么 JVM 的初始化操作其实就是HotSpot 执行启动的前提条件,并且在初始化过程中还涉及 HotSpot 中一些核心模块的初始化(比如初始化 os 模块、初始化全局数据结构、启动线程、初始化全局模块等),所以了解HotSpot 的初始化过程对于理解其整体架构具有非常重要的意义。本章接下来将会围绕HotSpot 中的部分构成模块及其初始化过程进行讲解。5.1 HotSpot的构成模块在前面几个章节中,本书详细地讲解了关于 HotSpot 源码的部分内容,其中涵盖了HotSpot 的源码下载、编译以及使用 GDB 工具进行 Debug;在上一章,本书又深入到了Launcher 的源码细节中,为大家剖析了 Launcher 是如何启动 HotSpot 的。而本章则会延续之前的内容,为大家深入剖析 HotSpot 的初始化过程。我们都知道是由 Launcher 负责维护 JVM 的整个生命周期,那么当 Launcher 中的启动函数 m