携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
我们继续来深入学习main方法啊。
JLI_Launch
我们在这个方法打个断点,b:java.c: 187
对应我们下面的 这个代码
由于这个找分支比较麻烦,后续直接看源码就好。
这个方法是从jar包中manifest文件或者命令行读取用户使用的JDK版本,看看与当前jdk是否合适。
这里是一个开始一个结束,中间呢就是加载虚拟机的过程,所以我们跟进这个方法
LoadJavaVM
这个方法主要是做什么事呢?主要是检测这个库里面有没有这三个方法:
JVMInit
然后跳过一些不重要的方法,到这个方法进去看看:
注意啊,我们这个时候还在main线程里,这个main线程不是java的main线程噢,到这一步就是新创建一个线程了。
这个方法呢就是通过pthread_create创建一个javamain线程,然后通过pthread_join阻塞当前的main线程。
那当前线程阻塞,创建一个新的线程执行什么方法呢?执行的就是javaMain方法。
JavaMain
那这个方法里面干什么呢?这个方法里面有一个初始化虚拟机的方法,我们找一下:
这里面有个用jni创建虚拟机的方法,我们点进去看看:
找到这个方法,就是创建虚拟机的入口:
找到这个方法,这里是将创建的主线程与操作系统的线程进行关联(Attach the main thread to this os thread)
那这是怎么跟操作系统建立关联的呢?我们一路追踪,到这个方法
然后呢,该方法创建了一个OSThread,把操作系统创建的线程id取出,分配给OSThread
然后OSThread进入待运行状态,然后把OSThread和JavaThread建立关联:
关联是建立了,但是这个JavaThread还是存在虚拟机层面的啊,必须要映射到java层面,那怎么映射呢?
这里有一个初始化线程的方法,我们点进去看看
这一步才是把JavaThread映射到java层面去
初始化一个字符串main,然后调用线程的构造方法,构造一个main线程
加载主类
反射拿到main方法的id
然后我们的main线程就有了,之后拿到java主类,反射调用main方法。