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_45\bin\Java.exe,然后截取到绝对路径c:\jdk1.7.0_45\,判断c:\jdk1.7.0_45\bin\Java.dll文件是否存在,如果存在就把c:\jdk1.7.0_45\作为jre路径,如果不存在则判断c:\jdk1.7.0_45\jre\bin\Java.dll是否存在,如果存在这c:\jdk1.7.0_45\jre作为jre路径,如果不存在调用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\JavaRuntime
Environment\“当前JRE版本号”\JavaHome的路径为jre路径。

然后装载JVM.cfg文件。在我们的jdk目录中jre\bin\server和jre\bin\client都有JVM.dll文件存在,而Java正是通过JVM.cfg配置文件来管理这些不同版本的JVM.dll的。

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

2、装载JVM.dll

通过第一步已经找到了JVM的路径,Java通过LoadJavaVM来装入JVM.dll文件。装入工作很简单,就是调用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寄存器。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-09-20 14:54:34

JVM概述的相关文章

JVM概述 &amp; GC概述

参考: https://blog.csdn.net/seu_calvin/article/details/51404589 Oracle:Java Garbage Collection Basics span{color:red} 0. Java Garbage Collection Basics 学习记录 Java 概述 任何运行java程序的PC需要获取一个Java runtime environment,JRE由Java虚拟机(JVM),Java平台核心类和支持的Java平台库组成. 在J

java jvm概述

java jvm 有分层的思想. java类..java文件,源文件,源代码,源程序 编译器不能把源代码直接编译成0101,除非是java语言写的操作系统. windows认识的可执行文件是.exe文件,windows操作系统可以把.exe文件翻译成0101.

JAVA学习总结之JVM概述

参考博客 JVM理解其实并不难! JVM的内存区域划分 Java垃圾回收机制 JVM内存区域 由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分.在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程: 如上图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行.在整个程序执行过程中,JVM会用一段空

JConsole监控jvm

java程序jvm监控一直是个蛋疼的问题,无意中网上看到JDK自带JConsole 可以监控JVM并且支持可视化图形,就自己测试了一下. 在网上看到VisualVM也支持监控JVM,查了下发现这个是JConsole的升级版,还能监控和分析垃圾回收和线程. 首先JConsole这个是JDK里面自带的工具  在JAVA_HOME/bin目录下,今天主要测试远程监控JVM 1.设置好需要远程机器的Tomcat (这里我的机器是centos) 修改catalina.sh 在 ----- Execute

JVM性能优化,第2部分:编译器JVM

通过优锐课的java学习分享中,整理了部分关于JVM的相关知识点,分享给大家参考学习,如有不足之处,欢迎 补充! Java编译器在JVM性能优化系列的第二篇文章中占据中心位置. Eva Andreasson介绍了不同种类的编译器,并比较了客户端,服务器和分层编译的性能结果.最后,她概述了常见的JVM优化,例如消除死代码,内联和循环优化. Java编译器是Java著名的平台的独立性的来源.软件开发人员会尽力编写最好的Java应用程序,然后编译器会在幕后进行工作,以为目标目标平台生成高效且性能良好的

热烈庆祝【深入浅出Java虚拟机——入门篇】培训课程在51CTO上线了

我的视频[深入浅出Java虚拟机--入门篇]在51CTO学院上线了. 想了解的可以点击: http://edu.51cto.com/course/course_id-1952.html 课程框架如下: 1.jvm概述 2.java规范和JVM规范简述 3.生活中的数字在计算机中的表示 4.jvm内存划分 5.jvm内存模型 6.jvm调试跟踪参数 7.jvm内存控制上 8.jvm内存控制下 9.jvm中class的装载过程 10.jvm中classloader的设计模式 11.jvm中有关cla

JAVA初步了解

一. 计算机基础知识 1.计算机??电子计算机(电脑),是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备.由硬件和软件所组成,没有安装任何软件的计算机称为裸机.常见的形式有台式计算机.笔记本计算机.大型计算机等.??应用:(1)科学计算,(2)数据处理,(3)自动控制,(4)计算机辅助设计,(5)人工智能,(6)多媒体应用,(7)计算机网络......2.计算机硬件和软件??硬件是指计算机系统中由电子,机械和光电元件等组成各种物理装置的总称.这些物理装置按系统结构要求构成了一个

JVM的GC概述

JVM的GC概述 GC即垃圾回收,是指jvm用于释放那些不再使用的对象所占用的内存.在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能. 有些垃圾收集专用于特殊的应用程序.比如,实时应用程序主要是为了避免垃圾收集中断,而大多数OLTP应用程序则注重整体效率.垃圾收集的目的在于清除不再使用的对象.gc通过确定对象是否被活动对象引用来确定是否收集该对象.两种常用的方法是引用计数和对象引用遍历.引用计数引用计数存储对特定对象的所有引用数,也就是说,当应用程序创建引用以及引用超出范围时,jvm

JVM内存管理------JAVA语言的内存管理概述

引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓狂的内存溢出和泄露的问题. 可怕的事情还不只如此,有些使用其它语言开发的程序员,给JAVA程序员扣上了一个"不懂内存"的帽子,这着实有点让人难以接受.毕竟JAVA当中没有malloc和delete.没有析构函数.没有指针,刚开始接触JAVA的程序员们又怎么可能接触内存这一部分呢,更何况有不