jvm编程语言-JVM系列

(一)JVM运行机制——启动流程

2020-04-19  本文已影响0人  十六线程序员

最近重新学习了JVM,从源码角度来深入理解JVM,后续将分多个章节对JVM进行介绍。

这边主要介绍JVM的启动流程,并从源码的角度去加强理解。
注:因为部分源码过长,图片截取部分源码并不完整,具体可以去看jdk的源码

JVM启动流程

jvm启动流程图.png
1. 执行java命令启动虚拟机,虚拟机的启动入口位于java.c文件下的JavaMain()方法
java.c目录.png
JavaMain()方法.png

2. 装载配置。这一步的目的是了根据当前JRE环境的路径和系统版本寻找jvm.cfg文件,并从该文件中确定jvm的类型,具体实现如下:
(1)首先通过java_md.c文件下的GetJREPath()方法获取JRE环境的路径

GetJREPath().png
(2)其次调用java_md.c文件下ReadKnownVMs()方法读取JRE路径\lib\ARCH(CPU构架)\jvm.cfg文件,其中ARCH是通过调用GetArchPath()方法获取的,在window下有三种情况:amd64、ia64和i386
ReadKnownVMs().png
GetArchPath().png
例如在这里,楼主本地的jvm.cfg位置如下图所示,CPU构架为amd64
jvm.cfg文件位置.png
(3)在获取到jvm.cfg文件之后,通过调用CheckJvmType()方法确定JVM的类型,先判断是否通过-J、-XXaltjvm=或-J-XXaltjvm=参数指定,如果没有,则读取JVM.cfg文件中配置的第一个类型
CheckJvmType().png
3. 根据配置寻找jvm.dll文件。根据上一步获取到的JVM类型,调用GetJVMPath()方法获取到jvm.dll文件的路径
image.png
4.初始化JVM。这一步包括装载jvm.dll动态连接库、初始化jvm.dll并挂接到JNIEnv(JNI调用接口)实例、调用JNIEnv实例装载并处理class类
(1)装载jvm.dll动态连接库。这一步是由java.c文件调用java_md.c中的LoadJavaVM()方法实现的。
java.c调用LoadJavaVM()方法.png
java_md.c文件中的LoadJavaVM()方法.png

(2)初始化jvm.dll并挂接到JNIEnv(JNI调用接口)实例。通过java.c文件中的InitializeJVM()方法完成。

InitializeJVM()方法.png
在main函数中定义的JNIEnv就能够获取到该方法返回的实例,就可以对class文件进行处理了
main函数中的JNIEnv类型的指针.png
(3)调用JNIEnv实例装载并处理class类。根据需要执行的文件类型,调用不同的方法进行类的加载。具体实现如下:
如果是执行class方法的话,main函数直接调用java.c中LoadMainClass()方法装载该类。
LoadMainClass().png
其次,如果要执行的文件类型是jar的话,具体步骤如下图(楼主在java.c中并没有发现GetMainClassName函数,这里留个疑问,待我去深入理解)
执行jar.png
5.找到main方法并运行
上一步中已经通过LoadMainClass()方法获取到该类,main函数中调用JNIEnv实例的GetStaticMethodID()方法查找装载的class主类中的main()方法,然后判断该方法是否为public,最后调用JNIEnv实例的CallStaticVoidMethod()方法调用该java类的main方法
image.png

总结

以上就是 JVM启动流程及涉及到的方法,对于源码的解读后续我会继续总结和学习。

上一篇 下一篇

猜你喜欢

热点阅读