JVM工作原理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
JVM工作原理
1.JVM是什么?
为java程序提供运行环境,将java字节码文件翻译成机器可执行的二进制程序。
2. JVM装入:操作系统通过jdk中的java.exe来装入JVM
①、创建JVM装载环境和配置
②、装载JVM.dll
③、初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例
④、调用JNIEnv实例装载并处理class类
3. JVM装入环境,JVM提供的方式是操作系统的动态连接文件
基于Windows的实现的分析
①、查找jre路径
Java是通过GetApplicationHome api来获得当前的Java.exe绝对路径
②、查找JVM.dll
F:\Java\jdk1.6.0_20\jre\bin\java.dll
或GetPublicJREHome
HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment
③、装载JVM.cfg文件
F:\Java\jdk1.6.0_20\jre\lib\i386\JVM.cfg
jdk目录中jre\bin\server和jre\bin\client都有JVM.dll文件存在,而Java 正是通过JVM.cfg配置文件来管理这些不同版本的JVM.dll的
主要参数:
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR
KNOWN表示JVM存在ALIASED_TO表示给别的JVM取一个别名
WARN表示不存在时找一个JVM替代ERROR表示不存在抛出异常
在运行Java XXX是,Java.exe会通过CheckJVMType来检查当前的JVM类型,Java可以通过两种参数的方式来指定具体的JVM类型,一种按照JVM.cfg文件中的JVM名称指定,第二种方法是直接指定:
①、Java –J
②、Java -XXaltJVM= 或Java -J-XXaltJVM=
如果是第一种参数传递方式,CheckJVMType函数会取参数…-J‟后面的JVM名称,然后从已知的JVM配置参数中查找如果找到同名的则去掉该JVM名称前的…-‟直接返回该值;而第二种方法,会直接返回“-XXaltJVM=”或“-J-XXaltJVM=”后面的JVM类型名称。如果在运行Java时未指定上面两种方法中的任一一种参数,CheckJVMType会取配置文件中
第一个配置中的JVM名称,去掉名称前面的…-‟返回该值。CheckJVMType函数的这个返回值会在下面的函数中汇同jre路径组合成JVM.dll的绝对路径。如果没有指定这会使用JVM.cfg中第一个定义的JVM.可以通过set _Java_LAUNCHER_DEBUG=1在控制台上测试.
最后获得JVM.dll的路径,JRE路径+\bin+\JVM类型字符串+\JVM.dll就是JVM的文件路径了,但是如果在调用Java程序时用-XXaltJVM=参数指定的路径path,就直接用path+\JVM.dll文件做为JVM.dll的文件路径
JVM.dll的路径=JRE路径+\bin+\JVM类型字符串+\JVM.dll。但是如果在调用Java 程序时用-XXaltJVM=参数指定的路径path,就直接用path+\JVM.dll文件做为JVM.dll 的文件路径.
4、装载JVM.dll
找到了JVM的路径,Java通过LoadJavaVM来装入JVM.dll文件.装入工作很简单就是调用Windows API函数:
LoadLibrary装载JVM.dll动态连接库.然后把JVM.dll中的导出函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs挂接到InvocationFunctions 变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上。JVM.dll的装载工作宣告完成。
5、初始化JVM,获得本地调用接口
这样就可以在Java中调用JVM的函数了.调用InvocationFunctions ->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法获得JNIEnv结构的实例.
6、运行Java程序
Java程序有两种方式
①、Java -jar XXX.jar运行
Java.exe调用GetMainClassName函数,该函数先获得JNIEnv实例然后调用Java类Java.util.jar.JarFileJNIEnv中方法getManifest()并从返回的Manifest对象中取getAttributes("Main-Class")的值即jar包中文件:META-INF/MANIFEST.MF指定的Main-Class的主类名作为运行的主类。之后main函数会调用Java.c中LoadClass 方法装载该主类(使用JNIEnv实例的FindClass)。main函数直接调用Java.c中LoadClass方法装载该类。
②、执行class方法
main函数直接调用Java.c中LoadClass方法装载该类然后main函数调用JNIEnv 实例的GetStaticMethodID方法查找装载的class主类中
“public static void main(String[] args)”方法,并判断该方法是否为public方法,然后调用JNIEnv实例的
CallStaticVoidMethod方法调用该Java类的main方法。