JVM概述


JVM是什么

JVM全称是Java Virtual Machine(java虚拟机)。它之所以被称之为是“虚拟”的,就是由于它不过由一个规范来定义的抽象计算机。我们平时常常使用的Sun HotSpot虚拟机不过当中一个详细的实现(另外还有BEA JRockit、IBM J9等等虚拟机)。

JVM的设计目标是提供一个基于抽象规格描写叙述的计算机模型,为解释程序开发者提供非常好的灵活性,同一时候也确保Java代码可在符合该规范的不论什么系统上执行。JVM对事实上现的某些方面给出了详细的定义,特别是对Java可执行代码。即字节码(Bytecode)的格式给出了明白的规格。这一规格包含操作码和操作数的语法和数值、标识符的数值表示方式、以及Java类文件里的Java对象、常量缓冲池在JVM的存储映象。这些定义为JVM解释器开发者提供了所需的信息和开发环境。

Java的设计者希望给开发者以随心所欲使用Java的自由。

JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种基于下层的操作系统和硬件平台并利用软件方法来实现的抽象的计算机。能够在上面运行java的字节码程序。


JRE/JDK/JVM是什么关系

JRE(JavaRuntimeEnvironment,Java执行环境),也就是Java平台。

全部的Java 程序都要在JRE下才干执行。普通用户仅仅须要执行已开发好的java程序,安装JRE就可以。

JDK(Java Development Kit)是程序开发人员用来来编译、调试java程序用的开发工具包。

JDK的工具也是Java程序。也须要JRE才干执行。为了保持JDK的独立性和完整性,在JDK的安装过程中。JRE也是安装的一部分。

所以,在JDK的安装文件夹下有一个名为jre的文件夹,用于存放JRE文件。

JVM(JavaVirtualMachine,Java虚拟机)是JRE的一部分

它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完好的硬件架构,如处理器、堆栈、寄存器等。还具有对应的指令系统。

Java语言最重要的特点就是跨平台执行。使用JVM就是为了支持与操作系统无关,实现跨平台。


JVM的生命周期

当启动一个Java程序时,一个虚拟机实例也就诞生了。

当该程序关闭退出,这个虚拟机实例也就随之消亡。假设在同一台计算机上同一时候执行三个Java程序。将得到三个Java虚拟机实例。

每一个Java程序都执行于它自己的Java虚拟机实例中。

JVM实例相应了一个独立执行的java程序,它是进程级别。

1、启动。

启动一个Java程序时。一个JVM实例就产生了,不论什么一个拥有publicstatic void main(String[] args)函数的class都能够作为JVM实例执行的起点

2、执行。

main()作为该程序初始线程的起点,不论什么其它线程均由该线程启动。

JVM内部有两种线程:守护线程和非守护线程。main()属于非守护线程,守护线程通常由JVM自己使用,java程序也能够标明自己创建的线程是守护线程

3、消亡。

当程序中的全部非守护线程都终止时,JVM才退出;若安全管理器同意,程序也能够使用Runtime类或者System.exit()来退出


JVM执行原理

操作系统装入JVM是通过jdk中Java.exe来完毕,通过以下4步来完毕JVM环境。

1、JVM装入环境。

JVM提供的方式是操作系统的动态连接文件。既然是文件那就存在一个装入路径的问题,Java是怎么找这个路径的呢?以下基于Windows的实现的分析。

首先查找jre路径,Java是通过GetApplicationHomeapi来获得当前的Java.exe绝对路径,c:jdk1.7.0_45inJava.exe,然后截取到绝对路径c:jdk1.7.0_45,推断c:jdk1.7.0_45inJava.dll文件是否存在,假设存在就把c:jdk1.7.0_45作为jre路径。假设不存在则推断c:jdk1.7.0_45jreinJava.dll是否存在,假设存在这c:jdk1.7.0_45jre作为jre路径。假设不存在调用GetPublicJREHome查HKEY_LOCAL_MACHINESoftwareJavaSoftJavaRuntime Environment“当前JRE版本”JavaHome的路径为jre路径。

然后装载JVM.cfg文件。

在我们的jdk文件夹中jreinserver和jreinclient都有JVM.dll文件存在。而Java正是通过JVM.cfg配置文件来管理这些不同版本号的JVM.dll的。

最后获得JVM.dll的路径,JRE路径+in+JVM类型字符串+JVM.dll就是JVM的文件路径了,可是假设在调用Java程序时用-XXaltJVM=參数指定的路径path,就直接用path+JVM.dll文件做为JVM.dll的文件路径。

2、装载JVM.dll

通过第一步已经找到了JVM的路径,Java通过LoadJavaVM来装入JVM.dll文件。

装入工作非常easy,就是调用Windows API函数:

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

JVM.dll的装载工作宣告完毕。

3、初始化JVM。

挂接到JNIENV(JNI调用接口)实例,获得本地调用接口,这样就能够在Java中调用JVM的函数了。调用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法获得JNIEnv结构的实例。

4、执行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主类中“publicstatic void main(String[] args)”方法,并推断该方法是否为public方法,然后调用JNIEnv实例的CallStaticVoidMethod方法调用该Java类的main方法。


JVM体系结构

JVM的体系结构图例如以下:

 

主要包含两个子系统和两个组件: Classloader(类装载器) 子系统,Execution engine(执行引擎) 子系统;Runtime data area (执行时数据区域)组件。 Native interface(本地接口)组件。

Class loader子系统:依据给定的全限定名类名(如java.lang.Object)来装载class文件的内容到 Runtime data area中的method area(方法区域)。

Execution engine子系统:运行classes中的指令。方法的字节码是由Java虚拟机的指令序列构成的。每一条指令包括一个单字节的操作码,后面尾随0个或多个操作数。运行引擎运行字节码时,首先取得一个操作码,假设操作码有操作数,取得它的操作数。

它运行操作码和尾随的操作数规定的动作,然后再取得下一个操作码。这个运行字节码的过程在线程完毕前将一直持续。不论什么JVM实现的核心是Execution engine。换句话说:Sun 的JDK 和IBM的JDK好坏主要取决于他们各自实现的Execution engine的好坏。

Native interface组件 :与nativelibraries交互,是其他编程语言交互的接口。Java里声明为native的方法多数在jdk/src/<platform>/native里能够找到。当中<platform>能够是share,也就是平台中立的代码;也能够是某个详细平台。这个native文件夹里的结构跟Java源代码结构一样是按包名来组织的。

只是须要提醒的是。这些native方法不是“JVM”的,是“类库”的。不在JVM里面。

Runtime data area 组件:Java虚拟机定义了若干种程序执行时使用到的执行时数据区,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁。如堆、方法区。另外一种则是与线程一一相应,随线程的開始和结束而创建和销毁,如Java栈,PC寄存器。

原文地址:https://www.cnblogs.com/brucemengbm/p/7240695.html