jvm15源码阅读之vm创建和初始化操作列表
这里承接之前的前奏部分,在JavaMain方法中进行jvm创建和初始化的初步解析.
1 InitializeJVM方法
此方法是初始化jvm的核心方法,很多需要初始化的操作都在此方法内完成.
进入此方法后,主要做的就是创建jvm,是由CreateJavaVM方法来完成的.可见,初始化就包含在内了.此处该方法就是之前的通过链接动态库加载jvm中实现的
具体在jni.cpp文件中实现
方法名本身使用了宏,表明是jni的本地方法,可供调用,这里实际只是调用了JNI_CreateJavaVM_inner方法,该方法也使用了很多指导编译的宏,其中核心方法是调用了Threads::create_vm方法来创建vm,进入该方法,此方法就是具体创建并初始化jvm的逻辑实现部分.
2 Threads::create_vm方法
Threads::create_vm方法是创建并初始化jvm的入口,由于涉及初始化的东西太多,这里以表格的形式给出该方法内所直接出现全部操作.
以上71种方法按照出现的顺序代表着71种不同的操作,都是直接出现在Threads::create_vm方法中的,每个方法几乎都相当于一个小的系统,非常精致.
3 vm创建初和始化的初步逻辑梳理
这里以在不低于linux内核2.6版本的系统中执行java命令为例,来说明jvm创建和初始化的初步流程.
首先,由bash进程启动一个最初的线程,执行JavaMain方法,这里这个线程还不是jvm的vm线程,这里把它当作0号线程.
其次,在JavaMain方法中创建main_thread线程和vm线程,这里的main_thread线程只是普通的执行方法的线程,该线程在初始化阶段并没有启动.而vm线程才是jvm主线程(这里这么说也是有原因的,之后会解释),也就是primordial thread线程,但是并没有设置堆和栈的大小,使用的都是默认值,其实这个vm线程只负责处理与vm相关的事件并把事件委派给别的线程来处理,然后自身处于阻塞状态.
最后,一切就绪后开始进行方法调用,启动main_thread执行main方法.
总结起来就是,由bash进程启动0号线程,0号线程启动vm线程,之后vm线程处于阻塞转态,直到有vm事件到来.至于为什么在0号线程中创建vm见文章https://bugs.openjdk.java.net/browse/JDK-6316197.
这只是初步的创建和初始化逻辑,具体的会在后续进行深入解析.
4 后续安排
首先会对涉及初始化的71个方法进行详细的分析,这其中会涉及到java的线程模型,方法调用机制及类的初始化和对象的相关操作,内容会很多.
其次会对main方法的调用进行深入的分析,这会涉及一些cpp的核心概念,所以本人在分析main方法调用之前会先做一个cpp核心概念的介绍.
最后会结合java的调试来给出在cpp层面的问题排查.