文档章节

JVM工作原理那些事儿

陶邦仁
 陶邦仁
发布于 2012/11/01 22:00
字数 1672
阅读 1010
收藏 23

JVM工作原理和特点

我们运行和调试Java程序的时候,经常会提到一个JVM的概念.JVM是Java程序运行的环境,但是他同时是一个操作系统的一个应用程序也是一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间.

首先来说一下JVM工作原理中的jdk这个东西,不管你是初学者还是高手,是j2ee程序员还是j2se程序员,jdk总是在帮我们做一些事情.我们在了解Java之前首先大师们会给我们提供说jdk这个东西.它在Java整个体系中充当着什么角色呢?我很惊叹sun大师们设计天才,能把一个如此完整的体系结构化的如此完美.jdk在这个体系中充当一个生产加工中心,产生所有的数据输出,是所有指令和战略的执行中心.本身它提供了Java的完整方案,可以开发目前Java能支持的所有应用和系统程序.这里说一个问题,大家会问,那为什么还有j2me,j2ee这些东西,这两个东西目的很简单,分别用来简化各自领域内的开发和构建过程.jdk除了JVM之外,还有一些核心的API,集成API,用户工具,开发技术,开发工具和API等组成

好了,废话说了那么多,来点于主题相关的东西吧.JVM在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也就虚拟计算机.操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境.

1.创建JVM装载环境和配置

2.装载JVM.dll

3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例

4.调用JNIEnv实例装载并处理class类。

一.JVM装入环境

JVM提供的方式是操作系统的动态连接文件.既然是文件那就一个装入路径的问题,Java是怎么找这个路径的呢?当你在调用Javatest的时候,操作系统会在path下在你的Java.exe程序,Java.exe就通过下面一个过程来确定JVM的路径和相关的参数配置了.下面基于Windows的实现的分析.

◆首先查找jre路径,Java是通过GetApplicationHomeapi来获得当前的Java.exe绝对路径,c:\j2sdk1.4.2_09\bin\Java.exe,那么它会截取到绝对路径c:\j2sdk1.4.2_09\,判断c:\j2sdk1.4.2_09\bin\Java.dll文件是否存在,如果存在就把c:\j2sdk1.4.2_09\作为jre路径,如果不存在则判断c:\j2sdk1.4.2_09\jre\bin\Java.dll是否存在,如果存在这c:\j2sdk1.4.2_09\jre作为jre路径.如果不存在调用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\JavaRuntimeEnvironment\“当前JRE版本号”\JavaHome的路径为jre路径。

◆然后装载JVM.cfg文件JRE路径+\lib+\ARCH(CPU构架)+\JVM.cfgARCH(CPU构架)的判断是通过Java_md.c中GetArch函数判断的,该函数中windows平台只有两种情况:WIN64的‘ia64’,其他情况都为‘i386’。以我的为例:C:\j2sdk1.4.2_09\jre\lib\i386\JVM.cfg.主要的内容如下:

-clientKNOWN-serverKNOWN-hotspotALIASED_TO-client-classicWARN-nativeERROR-greenERROR在我们的jdk目录中jre\bin\server和jre\bin\client都有JVM.dll文件存在,而Java正是通过JVM.cfg配置文件来管理这些不同版本的JVM.dll的.通过文件我们可以定义目前jdk中支持那些JVM,前面部分(client)是JVM名称,后面是参数,KNOWN表示JVM存在,ALIASED_TO表示给别的JVM取一个别名,WARN表示不存在时找一个JVM替代,ERROR表示不存在抛出异常.

◆在运行JavaXXX是,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

通过第一步已经找到了JVM的路径,Java通过LoadJavaVM来装入JVM.dll文件.装入工作很简单就是调用WindowsAPI函数:

LoadLibrary装载JVM.dll动态连接库.然后把JVM.dll中的导出函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs挂接到InvocationFunctions变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上。JVM.dll的装载工作宣告完成。

三:初始化JVM,获得本地调用接口

这样就可以在Java中调用JVM的函数了.调用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法获得JNIEnv结构的实例.

四:运行Java程序.

Java程序有两种方式一种是jar包,一种是class。

如果是运行jar,Java-jarXXX.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方法。

© 著作权归作者所有

共有 人打赏支持
陶邦仁
粉丝 1635
博文 420
码字总数 1483887
作品 0
海淀
技术主管
私信 提问
5年时间,Java程序员如何从小白晋升为大牛

程序员之言 2018-06-25 在程序界流行着一种默认的说法叫“黄金5年”,也就是一个程序员从入职的时候算起,前五年的选择直接影响着整个职业生涯中的职业发展方向和薪资走向。 因此如何走好这5...

ydx20151111
2018/06/25
0
0
学习Java和Spring Boot Cloud ,不妨看看这个

专注于编程、互联网动态。最终将总结的技术、心得、经验(数据结构与算法、源码分析等)分享给大家,这里不只限于技术!还有职场心得、生活感悟、以及面经。 1 java版web项目 java版web项目,...

b644rofp20z37485o35m
2018/05/04
0
0
ThreadLocal的那些事儿

什么是ThreadLocal? 顾名思义它是local variable(线程局部变量)。 它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而...

陶邦仁
2012/09/07
0
2
效率编程 之「对于所有对象都通用的方法」

温馨提示:本系列博文(含示例代码)已经同步到 GitHub,地址为「java-skills」,欢迎感兴趣的童鞋、,纠错。 第 1 条:覆盖时请遵守通用约定 待续…… ———— ☆☆☆ —— 返回 -> 那些年...

qq_35246620
2018/05/27
0
0
数人云Meetup | 服务网格:ServiceMesh Is Coming

这是微服务容器如日中天的时代, 这是Kubernetes一统天下的时代, 这是CloudNative大势已成的时代, 这是传统企业进行互联网转型的时代, 在过去三年中,微服务因服务可独立部署并互相隔离的...

数人云
2017/11/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Hive性能优化

Hive设置参数的三种方法 Hive提供三种可以改变环境变量的方法,分别是:(1)、修改${HIVE_HOME}/conf/hive-site.xml配置文件;(2)、命令行参数;(3)、在已经进入cli时进行参数声明。下面...

hblt-j
7分钟前
0
0
快速使用github发布axure原型

前言 axure生成的原型图可以在自带的Axure share上使用,公司内网也可以直接放在本地访问,也可以打包成html文档给研发同事访问。这里我只是想将我的作品传到github上,并使其他人可以远程访...

铸剑为犁413
8分钟前
0
0
零基础学算法->质数

质数的定义 质数(Prime number),又称素数,指在大于1的自然数中,除了1和该数自身外,无法被其他自然数整除的数(也可定义为只有1与该数本身两个正因数的数) 大于1的自然数若不是素数,则...

tedzheng
19分钟前
0
0
C++程序中可以没有using namespace std;这一句吗

可以啊、、只是命名空间的声明而已。意思就是说下面的函数,如果有和stl库里面一个名字的,就是用的stl的函数 C++ using namespace std 详解  所谓namespace,是指标识符的各种可见范围。C...

天王盖地虎626
20分钟前
0
0
string类回顾

writeademo
24分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部