JVM启动流程

1. 配置JVM装载环境

JVM的环境创建包括两部分: JVM.dll文件的查找和装载

  • JVM.dll文件的查找:首先查找系统环境变量中的PATH路径中有没有JVM的相关配置,如果没有,则继续查找环境变量中的JAVA_HOME路径中的JVM.dll。若在JAVA_HOME中也找不到,就会在注册表中查找,如果连注册表里都找不到,JVM就无法启动了。
  • JVM.dll文件的装载:LoadLibrary方法装载JVM.dll动态连接库。然后把JVM.dll文件中定义的函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs绑定到InvocationFunctions变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上;

2. 解析虚拟机参数

将JVM环境装入内存后,接下来要做的就是解析JVM的参数

  1. JVM在启动时,会将传递给它的命令行参数存储到一个字符串数组,之后JVM会遍历该数组,解析每个参数
  2. JVMM会根据参数的格式和语义进行解析和处理,常见的虚拟机参数包括

    • 标准虚拟机参数: -Xms: 堆的最小值, -Xmx堆的最大值, -Xmn: 新生代的大小, Xss: 每个线程分配的内存大小
    • 启动类参数: 如 -classpath: 启动类路径, -D: 系统属性 等
    • 扩展参数L, 如 -XX: 用于JVM的非标选项, 如性能调优、垃圾回收等
  3. 解析完成后,JVM会对传入的参数进行可行性验证,如果验证可行,则JVM会根据参数的含义和配置,进行对应的设置操作,反之则会抛出异常信息

3. 设置线程栈大小

在解析虚拟机参数的过程中,如果设置了Xss,就会按照Xss配置IDE大小来设置线程栈大小,若没有传入Xss,则根据操作系统的不同,读取对应系统的配置文件,来对线程栈大小进行设置。

4. 执行程序的main方法

  1. 新建JVM实例

    执行ContinueInNewThread函数,创建一个新的线程来执行新建JVM实例的操作

  2. 寻找main函数并且执行

    1. 接着会进入ContinueInNewThread0函数,其将JavaMain作为参数传入。这个函数将会在新的线程中执行JavaMain函数

    2. 载入主类后获取主类中的主方法并执行,一旦主方法开始执行,Java程序就会开始快速运转了,直到走到主方法的最后一行才会return返回

图示整个执行过程

image-20230306164716949