深入学习main方法(下)

117 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

我们继续来深入学习main方法啊。

JLI_Launch

我们在这个方法打个断点,b:java.c: 187

image.png

对应我们下面的 这个代码

image.png

由于这个找分支比较麻烦,后续直接看源码就好。

这个方法是从jar包中manifest文件或者命令行读取用户使用的JDK版本,看看与当前jdk是否合适。

image.png

这里是一个开始一个结束,中间呢就是加载虚拟机的过程,所以我们跟进这个方法

image.png

LoadJavaVM

这个方法主要是做什么事呢?主要是检测这个库里面有没有这三个方法:

image.png

JVMInit

然后跳过一些不重要的方法,到这个方法进去看看:

image.png

注意啊,我们这个时候还在main线程里,这个main线程不是java的main线程噢,到这一步就是新创建一个线程了。

image.png

这个方法呢就是通过pthread_create创建一个javamain线程,然后通过pthread_join阻塞当前的main线程。

image.png

那当前线程阻塞,创建一个新的线程执行什么方法呢?执行的就是javaMain方法。

JavaMain

那这个方法里面干什么呢?这个方法里面有一个初始化虚拟机的方法,我们找一下:

image.png

这里面有个用jni创建虚拟机的方法,我们点进去看看:

image.png

找到这个方法,就是创建虚拟机的入口:

image.png

找到这个方法,这里是将创建的主线程与操作系统的线程进行关联(Attach the main thread to this os thread)

image.png

那这是怎么跟操作系统建立关联的呢?我们一路追踪,到这个方法

image.png

然后呢,该方法创建了一个OSThread,把操作系统创建的线程id取出,分配给OSThread

image.png

然后OSThread进入待运行状态,然后把OSThread和JavaThread建立关联:

image.png

关联是建立了,但是这个JavaThread还是存在虚拟机层面的啊,必须要映射到java层面,那怎么映射呢?

这里有一个初始化线程的方法,我们点进去看看

image.png

这一步才是把JavaThread映射到java层面去

image.png

初始化一个字符串main,然后调用线程的构造方法,构造一个main线程

image.png

加载主类

image.png

反射拿到main方法的id

image.png

然后我们的main线程就有了,之后拿到java主类,反射调用main方法。

image.png