深度剖析JVM虚拟机

上传人:飞*** 文档编号:35677382 上传时间:2018-03-19 格式:DOC 页数:39 大小:564KB
返回 下载 相关 举报
深度剖析JVM虚拟机_第1页
第1页 / 共39页
深度剖析JVM虚拟机_第2页
第2页 / 共39页
深度剖析JVM虚拟机_第3页
第3页 / 共39页
深度剖析JVM虚拟机_第4页
第4页 / 共39页
深度剖析JVM虚拟机_第5页
第5页 / 共39页
点击查看更多>>
资源描述

《深度剖析JVM虚拟机》由会员分享,可在线阅读,更多相关《深度剖析JVM虚拟机(39页珍藏版)》请在金锄头文库上搜索。

1、JVM:Java Virtual Machine Java 虚拟机 JRE:Java Runtime Environment Java 运行时环境 ABI:Application Binary Interface 应用二进制接口,是一个程序在运行时应用的环境,也是一种可执 行文件的格式。操作系统都有自己的进程地址控件,硬件系统也各不相同;java 在所有的计算机上都使 用相同的 ABI; java 运行时环境 JRE,包括 java 虚拟机,是 java ABI 与各种硬件/操作系统 ABI 之间的桥梁。 1)java 源代码编译后生成的目标代码是一种字节码(bytecode),与其他语言不同

2、的是:java 的字 节码是一种中立结构的机器代码(不是任何现有系统上的二进制指令代码),通过 JVM 可以快速地解释 并运行在任何特定的计算机上。 2)java 程序的执行通过 JVM 实现; 3)一般情况下,JVM 是在运行 java 程序时调用的; 4)JVM 读取字节码程序,解释或翻译成实际的机器指令后再执行,实行了 java 的“一次编写,多处运行” 的特点; Java 虚拟机是什么虚拟机是什么 Java 虚拟机之所以称为“虚拟”,就是因为它仅仅是由一个规范来定义的抽象计算机。要运行某个 Java 程序,首先需要一个符合该规范的具体实现。 下面主要讨论这个规范本身。要理解 Java

3、虚拟机,你必须意识到,当你说“Java 虚拟机”时,可能指的是如下三种不同的东西: 抽象规范 一个具体的实现 一个运行中的虚拟机实例 Java 虚拟机抽象规范仅仅是个概念。该规范的具体实现,可能来自多个提供商,并存在多个平台上。 它或者完全用软件实现,或者以硬件和软件相结合的方式来实现。当运行一个 Java 程序的同时,也就在 运行了一个 Java 虚拟机实例。 对 JVM 规范的抽象说明是一些概念的集合,它们已经在书The Java Virtual Machine Specification (Java 虚拟机规范)中被详细地描述了;对 JVM 的具体实现要么是软件,要么是软件和硬件的组合,

4、 它已经被许多生产厂商所实现,并存在于多种平台之上;运行 Java 程序的任务由 JVM 的运行期实例单 个承担。在本文中我们所讨论的 Java 虚拟机(JVM)主要针对第三种情况而言。它可以被看成一个想象中 的机器,在实际的计算机上通过软件模拟来实现,有自己想象中的硬件,如处理器、堆栈、寄存器等, 还有自己相应的指令系统。JVM 在它的生存周期中有一个明确的任务,那就是运行 Java 程序,因此当 Java 程序启动的时候, 就产生 JVM 的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从 JVM 的体系结构 和它的运行过程这两个方面来对它进行比较深入的研究。 Java 虚拟

5、机的生命周期虚拟机的生命周期 一个运行时的 Java 虚拟机实例的天职就是:负责运行一个 Java 程序。当启动一个 Java 程序时, 一个虚拟机实例也就诞生了。当该程序关闭退出,这个虚拟机实例也就随之消亡。每个 Java 程序都运行 在于自己的 Java 虚拟机实例中。Java 虚拟机实例通过调用某个初始类的 main()方法来运行一个 Java 程序。而这个 main()方法必须是 public,static,返回值为 void。main()方法作为该程序初始线程的起 点,任何其他的线程都是由这个初始线程启动的。 Java 虚拟机内部有两种线程:守护线程和非守护线程。守护线程通常由虚拟机

6、自己使用的,比如执行垃圾收集任务的线程。但是,Java 程序也可以把它的创建 的任何线程标记为守护线程。 而 Java 程序中的初始线程,就是开始于 main()的那个,是非守护线程。只要有非守护线程在运行,那 么这个 Java 程序也在继续运行,只有该程序中所有的非守护线程都终止时,虚拟机实例将自动退出。 Java 虚拟机的体系结构虚拟机的体系结构 Java 虚拟机的结构分为:类装载子系统类装载子系统,执行引擎执行引擎,运行时数据区运行时数据区,本地方法接口本地方法接口。 其中运行时数据区又分为:方法区,堆,方法区,堆,Java 栈,栈,PC 寄存器,本地方法栈。寄存器,本地方法栈。 Jav

7、a 虚拟机结构图Java 虚拟机由五个部分组成:一组指令集、一组寄存器、一个栈、一个无用单元收集堆(Garbage- collected-heap)、一个方法区域。这五部分是 Java 虚拟机的逻辑成份,不依赖任何实现技术或组织方式,但 它们的功能必须在真实机器上以某种方式实现。 类装载子系统类装载子系统(classclass loaderloader) Java 虚拟机中,负责查找并装载类型的那部分称为类装载子系统。 Java 虚拟机有两种类装载器:启动类装载器和用户自定义类装载器。 启动类装载器是 Java 虚拟机实现的一部分。 用户自定义类装载器是 Java 程序的一部分。 类装载器的动

8、作: 1. 装载-查找并装载类型的二进制数据 2. 连接-执行验证,准备,以及解析(可选) 验证:确保被导入类型的正确性 准备:为类变量分配内存,并将其初始化为默认值 把类型中的符号引用换为直接引用 3. 初始化-把类变量初始化为正确的初始值 执行引擎执行引擎处于 JVM 的核心位置,在 Java 虚拟机规范中,它的行为是由指令集所决定的。尽管对于每条指令,规 范很详细地说明了当 JVM 执行字节码遇到指令时,它的实现应该做什么,但对于怎么做却言之甚少。 Java 虚拟机支持大约 248 个字节码。每个字节码执行一种基本的 CPU 运算,例如,把一个整数加到寄存 器,子程序转移等。Java 指

9、令集相当于 Java 程序的汇编语言。 由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。指令中操作数的数 量和大小是由操作符决定的。如果操作数比一个字节大,那么它存储的顺序是高位字节优先。例如,一个 16 位的参数存放时占用两个字节,其值为: 第一个字节*256+第二个字节字节码。 指令流一般只是字节对齐的。指令 tableswitch 和 lookup 是例外,在这两条指令内部要求强制的 4 字节 边界对齐。 Java 指令集 Java 虚拟机支持大约 248 个字节码。每个字节码执行一种基本的 CPU 运算,例如,把一个整数加到寄存 器,子程序转移等。Java

10、 指令集相当于 Java 程序的汇编语言。 Java 指令集中的指令包含一个单字节的操作符,用于指定要执行的操作,还有 0 个或多个操作数,提供操作 所需的参数或数据。许多指令没有操作数,仅由一个单字节的操作符构成。 虚拟机的内层循环的执行过程如下: do 取一个操作符字节; 根据操作符的值执行一个动作; while(程序未结束) 由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。指令中操作数的数 量和大小是由操作符决定的。如果操作数比一个字节大,那么它存储的顺序是高位字节优先。例如,一个 16 位的参数存放时占用两个字节,其值为: 第一个字节*256+第二个字节字

11、节码指令流一般只是字节对齐的。指令 tableswitch 和 lookup 是例外, 在这两条指令内部要求强制的 4 字节边界对齐。 运行时数据区运行时数据区 方法区方法区 在 Java 虚拟机中,被装载类型的信息存储在一个逻辑上被称为方法区的内存中。当虚拟机装载某个类 型时,它使用类装载器定位相应的 class 文件,然后读入这个 class 文件,然后将它传输到虚拟机中,紧 接着虚拟机提取其中的类型信息,并将这些信息存储到方法区。该类型中的类(静态)变量同样也是存 储在方法区中。方法区的大小不必固定,可以根据需要动态调整。方法区也可以被垃圾收集,因为虚拟 机允许通过用户定义的类装载器来动

12、态扩展 Java 程序,因此,一些类也会成为“不再引用”的类。 对于每个装载的类型,虚拟机都会在方法区中存储以下类型信息: 这个类型的全限定名。 这个类型的直接超类的全限定名(除非是 java.lang.Object,无超类) 这个类型是类类型还是接口类型。 这个类型的访问修饰符(public,abstract .) 任何直接超接口的全限定名的有序列表 除了上面列出的基本类型信息外,虚拟机还为每个被装载的类型存储以下信息 该类型的常量池 字段信息 方法信息 除了常量以外所有类(静态)变量 一个到类 ClassLoader 的引用 一个到 Class 类的引用 方法区与传统语言中的编译后代码或是

13、 Unix 进程中的正文段类似。它保存方法代码(编译后的 java 代码)和 符号表。在当前的 Java 实现中,方法代码不包括在无用单元收集堆中,但计划在将来的版本中实现。每个 类文件包含了一个 Java 类或一个 Java 界面的编译后的代码。可以说类文件是 Java 语言的执行代码文件。 为了保证类文件的平台无关性,Java 虚拟机规范中对类文件的格式也作了详细的说明。其具体细节请参考 Sun 公司的 Java 虚拟机规范。 堆堆 无用单元收集堆 Java 的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java 语言具有无用单元收集能力:它不给 程序员显式释放对象的能力。Java

14、 不规定具体使用的无用单元收集算法,可以根据系统的需求使用各种各 样的算法。 无用单元收集堆(Garbage-collected-heap)栈栈 Java 虚拟机的栈有三个区域:局部变量区、运行环境区、操作数区。 (1)局部变量区 每个 Java 方法使用一个固定大小的局部变量集。它们按照与 vars 寄存器的字偏移量来 寻址。局部变量都是 32 位的。长整数和双精度浮点数占据了两个局部变量的空间,却按照第一个局部变 量的索引来寻址。(例如,一个具有索引 n 的局部变量,如果是一个双精度浮点数,那么它实际占据了索引 n 和 n+1 所代表的存储空间。)虚拟机规范并不要求在局部变量中的 64 位

15、的值是 64 位对齐的。虚拟机提 供了把局部变量中的值装载到操作数栈的指令,也提供了把操作数栈中的值写入局部变量的指令。 (2)运行环境区 在运行环境中包含的信息用于动态链接,正常的方法返回以及异常传播。 动态链接 运行环境包括对指向当前类和当前方法的解释器符号表的指针,用于支持方法代码的动态链接。方法的 class 文件代码在引用要调用的方法和要访问的变量时使用符号。动态链接把符号形式的方法调用翻译成 实际方法调用,装载必要的类以解释还没有定义的符号,并把变量访问翻译成与这些变量运行时的存储结 构相应的偏移地址。动态链接方法和变量使得方法中使用的其它类的变化不会影响到本程序的代码。 正常的方法返回 如果当前方法正常地结束了,在执行了一条具有正确类型的返回指令时,调用的方法会得到一个返回值。 执行环境在正常返回的情况下用于恢复调用者的寄存器,并把调用者的程序计数器增加一个恰当的数值, 以跳过已执行过的方法调用指令,然后在调用者的执行环境中继续执行下去。 异常和错误传播 异常情况在 Java 中被称作 Error(错误)或 Exception(异常),是 Throwable 类的子类,在程序中的原因是: 动态链接错,如无法找到所需的 class 文件。运行时错,如对一个空指针的引用 程序使用了 throw 语句。 当异常发

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 教育/培训

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号