JVM的启动过程
为了分析Java的启动过程,需要查看JDK的源代码。可以从这里拿源代码:
从github里面clone好以后,查看java
的源代码:
java
这个程序,是C代码,查看java.c
的源代码。重点看JavaMain(...)
函数:
上面是一些关键的函数,比如RegisterThread()
和InitializeJVM(...)
。继续看JavaMain(...)
函数:
可以看到VM启动后,就是LoadMainClass()
,然后通过GetStaticMethodID
,来执行main
方法。
上面就是JavaMain(...)
的一个大概的执行过程。接着可以重点看下InitializeJVM(...)
这个函数:
在这里面,重点是CreateJavaVM(...)
这个函数.查找下它的定义位置:
可以看到,在JDK的源代码里面并没有CreateJavaVM(...)
的具体实现,它只是一个接口定义,而由传入的InvocationFunctions
来进行具体的定义。这一点可以从Java的标准化文档中找到:
Java Native Interface Specification: 5 - The Invocation API
从文档中可以看到CreateJavaVM(...)
是一个接口定义:
查找这个接口的定义位置:
看到java_md.c
里面的实现,打开这个文件看下:
可以看到JNI_CreateJavaVM
是从handle
里面来,而handle
是从LoadLibrary(...)
里面来。这个LoadLibrary(...)
函数的名字比较直观,可以想到是读取VM的native library,应该是跟各平台相关的。我下载的openjdk代码里没有具体实现,但是可以从hotspot的实现(HotSpot是标准的Java VM:GitHub - openjdk-mirror/jdk7u-hotspot )里面找到实现供参考:
这个dll_load
是各平台各自实现的,比如我们可以看bsd
平台的实现:
可以看到调用的就是平台标准的动态库调用dlopen
。可以看一下相关的dlopen
位置:
以上是对JVM的一个从入口到加载的简单分析。