电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

详解JVM工作原理和特点


发布日期:2018/10/12
 

JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Javaexe来完成通过下面步来完成JVM环境

创建JVM装载环境和配置

装载JVMdll

初始化JVMdll并挂界到JNIENV(JNI调用接口)实例

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

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

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

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

创建JVM装载环境和配置

装载JVMdll

初始化JVMdll并挂界到JNIENV(JNI调用接口)实例

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

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

首先查找jre路径Java是通过GetApplicationHome api来获得当前的Javaexe绝对路径c:\jsdk_\bin\Javaexe那么它会截取到绝对路径c:\jsdk_\判断c:\jsdk_\bin\Javadll文件是否存在如果存在就把c:\jsdk_\作为jre路径如果不存在则判断c:\jsdk_\jre\bin\Javadll是否存在如果存在这c:\jsdk_\jre作为jre路径.如果不存在调用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\当前JRE版本号\JavaHome的路径为jre路径

然后装载JVMcfg文件JRE路径+\lib+\ARCH(CPU构架)+\JVMcfgARCH(CPU构架)的判断是通过Java_mdc中GetArch函数判断的该函数中windows平台只有两种情况WINia其他情况都为i以我的为例C:\jsdk_\jre\lib\i\JVMcfg主要的内容如下

clientKNOWN

serverKNOWN

hotspotALIASED_TOclient

classicWARN

nativeERROR

greenERROR

在我们的jdk目录中jre\bin\server和jre\bin\client都有JVMdll文件存在而Java正是通过JVMcfg配置文件来管理这些不同版本的JVMdll的.通过文件我们可以定义目前jdk中支持那些JVM前面部分(client)是JVM名称后面是参数KNOWN表示JVM存在ALIASED_TO表示给别的JVM取一个别名WARN表示不存在时找一个JVM替代ERROR表示不存在抛出异常.在运行Java XXX是Javaexe会通过CheckJVMType来检查当前的JVM类型Java可以通过两种参数的方式来指定具体的JVM类型一种按照JVMcfg文件中的JVM名称指定第二种方法是直接指定它们执行的方法分别是Java JJava XXaltJVM=Java JXXaltJVM=如果是第一种参数传递方式CheckJVMType函数会取参数J后面的JVM名称然后从已知的JVM配置参数中查找如果找到同名的则去掉该JVM名称前的直接返回该值而第二种方法会直接返回XXaltJVM=JXXaltJVM=后面的JVM类型名称如果在运行Java时未指定上面两种方法中的任一一种参数CheckJVMType会取配置文件中第一个配置中的JVM名称去掉名称前面的返回该值CheckJVMType函数的这个返回值会在下面的函数中汇同jre路径组合成JVMdll的绝对路径如果没有指定这会使用JVMcfg中第一个定义的JVM可以通过set _Java_LAUNCHER_DEBUG=在控制台上测试.

最后获得JVMdll的路径JRE路径+\bin+\JVM类型字符串+\JVMdll就是JVM的文件路径了但是如果在调用Java程序时用XXaltJVM=参数指定的路径path就直接用path+\JVMdll文件做为JVMdll的文件路径.

装载JVMdll

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

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

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

运行Java程序.

Java程序有两种方式一种是jar包一种是class 运行jarJava jar XXXjar运行的时候Javaexe调用GetMainClassName函数该函数先获得JNIEnv实例然后调用Java类JavautiljarJarFileJNIEnv中方法getManifest()并从返回的Manifest对象中取getAttributes(MainClass)的值即jar包中文件METAINF/MANIFESTMF指定的MainClass的主类名作为运行的主类之后main函数会调用Javac中LoadClass方法装载该主类(使用JNIEnv实例的FindClass)main函数直接调用Javac中LoadClass方法装载该类如果是执行class方法main函数直接调用Javac中LoadClass方法装载该类

然后main函数调用JNIEnv实例的GetStaticMethodID方法查找装载的class主类中

public static void main(String[] args)方法并判断该方法是否为public方法然后调用JNIEnv实例的

CallStaticVoidMethod方法调用该Java类的main方法

JVM工作原理和特点介绍到这里

上一篇:用JNA保护你的传统代码

下一篇:使用Swing进行动态界面设计