快捷搜索:  as

Java虚拟机

一、 什么是Java虚拟机

Java虚拟机是一个想象中的机械,在实际的谋略机上经由过程软件模拟来实现。Java虚拟机有自己想象中的硬件,如处置惩罚器、客栈、寄存器等,还具有响应的指令系统。

1.为什么要应用Java虚拟机?

Java说话的一个异常紧张的特征便是与平台的无关性。而应用Java虚拟机是实现这一特征的关键。一样平常的高档说话假如要在不合的平台上运行, 至少必要编译成不合的目标代码。而引入Java说话虚拟机后,Java说话在不合平台上运行时不必要从新编译.

Java虚拟机樊篱了与详细平台相关的信息,使得Java说话编译法度榜样只需天生在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加改动地运行。Java虚拟机在履行字节码时,把字节码解释成详细平台上的机械指令履行。

2.谁必要懂得Java虚拟机

Java虚拟机是Java说话底层实现的根基,对Java说话感兴趣的人都应对Java虚拟机有个大年夜概的懂得。这有助于理解Java说话的一些性子,也有助于应用Java说话。

对付要在特定平台上实现Java虚拟机的软件职员,Java说话的编译器作者以及要用硬件芯片实现Java虚拟机的人来说,则必须深刻理解Java虚拟机的规范。

别的,假如你想扩展 Java说话,或是把其它说话编译成Java说话的字节码,你也必要深入地懂得Java虚拟机。

3.Java虚拟机支持的数据类型

Java虚拟机支持Java说话的基础数据类型如下:

byte://1字节有符号整数的补码 short://2字节有符号整数的补码 int://4字节有符号整数的补码 long://8字节有符号整数的补码 float://4字节IEEE754单精度浮点数 double://8字节IEEE754双精度浮点数 char://2字节无符号Unicode字符

险些所有的Java类型反省都是在编译时完成的。上面列出的原始数据类型的数据在 Java履行时不必要用硬件标记。操作这些原始数据类型数据的字节码(指令)本身就已经指出了操作数的数据类型,例如iadd、ladd、fadd和dadd指令都是把两个数相加,其操作数类型分外是int、long、float和double。

虚拟机没有给boolean(布尔)类型设置零丁的指令。boolean型的数据是由integer指令, 包括integer返回来处置惩罚的。boolean型的数组则是用byte数组来处置惩罚的。

虚拟机应用IEEE754款式的浮点数。不支持IEEE款式的较旧的谋略机,在运行Java数值谋略法度榜样时,可能会异常慢。

虚拟机支持的其它数据类型包括:

object//对一个Javaobject(工具)的4字节引用 returnAddress//4字节,用于jsr/ret/jsr-w/ret-w指令

注:Java数组被算作object处置惩罚。

虚拟机的规范对付object内部的布局没有任何特殊的要求。在Sun公司的实现中,对 object的引用是一个句柄,此中包孕一对指针:一个指针指向该object的措施表,另一个指向 该object的数据。

用Java虚拟机的字节码表示的法度榜样应该遵守类型规定。Java虚拟机的实现应回绝履行违反了类型规定的字节码法度榜样。

Java虚拟机因为字节码定义的限定彷佛只能运行于32位地址空间的机械上。然则可以创建一个Java虚拟机,它自动地把字节码转换成64位的形式。

从Java虚拟机支持的数据类型可以看出,Java对数据类型的内部款式进行了严格规定,这样使得各类Java虚拟机的实现对数据的解释是相同的,从而包管了Java的与平台无关性和可移植性。

二、 Java虚拟机体系布局

Java虚拟机由五个部分组成:一组指令集、一组寄存器、一个栈、一个无用单元网络堆(Garbage-collected-heap)、一个措施区域。这五部分是Java虚拟机的逻辑成份,不依附 任何实现技巧或组织要领,但它们的功能必须在真实机械上以某种要领实现。

Java指令集

Java虚拟机支持大年夜约248个字节码。每个字节码履行一种基础的CPU运算,例如,把一个整数加到寄存器,子法度榜样转移等。Java指令集相称于Java法度榜样的汇编说话。

Java指令集中的指令包孕一个单字节的操作符,用于指定要履行的操作,还有0个或多个操作数,供给操作所需的参数或数据。许多指令没有操作数,仅由一个单字节的操作符构成。虚拟机的内层轮回的履行历程如下:

do{ 取一个操作符字节; 根据操作符的值履行一个动作; }while(法度榜样未停止)

因为指令系统的简单性,使得虚拟机履行的历程十分简单,从而有利于前进履行的效率。

指令中操作数的数量和大年夜小是由操作符抉择的。假如操作数比一个字节大年夜,那么它存储的顺序是高位字节优先。例如,一个16位的参数寄放时占用两个字节,其值为: 第一个字节*256+第二个字节

字节码指令流一样平常只是字节对齐的。指令tableswitch和lookup是例外,在这两条指令内部 要求强制的4字节界限对齐。

寄存器

Java虚拟机的寄存器用于保存机械的运行状态,与微处置惩罚器中的某些专用寄存器类似。 Java虚拟机的寄存器有四种:

pc:Java法度榜样计数器。 optop:指向操作数栈顶真个指针。 frame:指向当前履行措施的履行情况的指针。 vars:指向当前履行措施的局部变量区第一个变量的指针。

Java虚拟机

Java虚拟机是栈式的,它不定义或应用寄存器来通报或吸收参数,其目的是为了包管指令集的简洁性和实现时的高效性(分外是对付寄存器数目不多的处置惩罚器)。所有寄存器都是32位的。

Java虚拟机的栈有三个区域:局部变量区、运行情况区、操作数区。

局部变量区

每个Java措施应用一个固定大年夜小的局部变量集。它们按照与vars寄存器的字偏移量来寻址。局部变量都是32位的。长整数和双精度浮点数盘踞了两个局部变量的空间,却按照第一个局部变量的索引来寻址。(例如,一个具有索引n的局部变量,假如是一个双精度浮点数,那么它实际盘踞了索引 n和n+1所代表的存储空间。)虚拟机规范并不要求在局部变量中的64位的值是64位对齐的虚拟机供给了把局部变量中的值装载到操作数栈的指令,也供给了把操作数栈中的值写入局部变量的指令。

运行情况区

在运行情况中包孕的信息用于动态链接,正常的措施返回以及非常传播。

动态链接

运行情况包括对指向当前类和当前措施的说冥器符号表的指针,用于支持措施代码的动态链接。措施的class文件代码在引用要调用的措施和要造访的变量时应用符号。动态链接把符号形式的措施调用翻译成实际措施调用,装载需要的类以解释还没有定义的符号, 并把变量造访翻译成与这些变量运行时的存储布局响应的偏移地址。动态链接措施和变量使得措施中应用的其它类的变更不会影响到本法度榜样的代码。

正常的措施返回

假如当前措施正常地停止了,在履行了一条具有精确类型的返回指令时,调用的措施会获得一个返回值。

履行情况在正常返回的环境下用于规复调用者的寄存器,并把调用者的法度榜样计数器增添一个恰当的数值,以跳过已履行过的措施调用指令,然后在调用者的履行情况中继承履行下去。

非常和差错传播

非常环境在Java中被称作Error(差错)或Exception(非常),是Throwable类的子类,在法度榜样中掉足的缘故原由是:①动态链接错,如无法找到所需的class文件。②运行时错,如对一个空指针的引用

法度榜样应用了throw语句。

当非常发生时,Java虚拟机采取如下步伐:

反省与当前措施相联系的catch子句表。每个catch子句包孕其有效指令范围,能够处置惩罚的非常类型,以及处置惩罚非常的代码块地址。

与非常相匹配的catch子句应该相符下面的前提:造成非常的指令在其指令范围之内 ,发生的非常类型是其能处置惩罚的非常类型的子类型。假如找到了匹配的catch子句,那么系统转移到指定的非常处置惩罚块处履行;假如没有找到非常处置惩罚块,重复探求匹配的catch子句的历程,直到当前措施的所有嵌套的catch子句都被反省过。

因为虚拟机从第一个匹配的catch子句处继承履行,以是catch子句表中的顺序是很紧张的。由于Java代码是布局化的,是以总可以把某个措施的所有的非常处置惩罚器都按序排列到一个表中,对随意率性可能的法度榜样计数器的值,都可以用线性的顺序找到相宜的非常处置惩罚块,以处置惩罚在该法度榜样计数器值下发生的非常环境。

假如找不到匹配的catch子句,那么当前措施获得一个"未截获非常"的结果并返回到当前措施的调用者,似乎非常刚刚在其调用者中发生一样。假如在调用者中仍旧没有找到响应的非常处置惩罚,那么系 统将调用一个缺省的非常处置惩罚块。

操作数栈区

机械指令只从操作数栈中取操作数,对它们进行操作,并把结果返回到栈中。选择栈布局的缘故原由是:在只有少量寄存器或非通用寄存器的机械(如Intel486)上,也能够高效地模拟虚拟机的行径。

操作数栈是32位的。它用于给措施通报参数,并从措施接管结果,也用于支持操作的参数,并保存操作的结果。

例如,iadd指令将两个整数相加。相加的两个整数应该是操作数栈顶的两个字。这两个字是由先前的指令压进客栈的。这两个整数将从客栈弹出、相加,并把结果压回到操作数栈中。每个原始数据类型都有专门的指令对它们进行必须的操作。每个操作数在栈中必要一个存储位置,除了long和double型,它们必要两个位置。

操作数只能被适用于其类型的操作符所操作。例如,压入两个int类型的数,假如把它们算作是一个long类型的数则是不法的。在Sun的虚拟机实现中,这个限定由字节码验证器强制推行。然则,有少数操作(操作符dupe和swap),用于对运行时数据区进行操作时是不斟酌类型的。

无用单元网络堆

Java的堆是一个运行时数据区,类的实例(工具)从平分配空间。Java说话具有无用单元网络能力:它不给法度榜样员显式开释工具的能力。Java不规定详细应用的无用单元网络算法,可以根据系统的需求应用各类各样的算法。

措施区

措施区与传统说话中的编译后代码或是Unix进程中的正文段类似。它保存措施代码 (编译后的java代码)和符号表。在当前的Java实现中,措施代码不包括在无用单元网络堆中,但计划在将来的版本中实现。每个类文件包孕了一个Java类或一个Java界面的编译后的代码。可以说类文件是 Java说话的履行代码文件。为了包管类文件的平台无关性,Java虚拟机规范中对类文件的款式也作了具体的阐明。其详细细节请参考Sun公司的Java虚拟机规范

三、 Java类文件(.class文件)

每个类文件包孕了一个Java类或一个Java界面的编译后的代码。可以说类文件是Java说话的履行代码文件。为了包管类文件的平台无关性,Java虚拟机规范中对类文件的款式也作了具体的阐明。其详细细节请参考Sun公司的Java虚拟机规范。

四、 Java芯片

因为Java说话是解释型说话,在一样平常的通用场置惩罚器上其运行速率比起编译型说话要慢很多。Sun公司为了进一步推广Java的利用,推出了Java芯片。这些芯片可以说是Java虚拟机的硬件实现。与通用芯片和解释器构成的虚拟机不合,Java芯片可以直接履行字节码,也便是说,字节码便是 Java芯片的指令集。这种用硬件实现的虚拟机当然要比软件模拟的虚拟机的速率要快得多。

Sun公司计划推出的Java芯片有三种:picoJava,mi-croJava和ultraJava。

picoJava是一个很小的Java内核芯片,其硅片面积只有25mm2。Sun公司筹备向其它公司让渡,以便其它公司可以定制自己的Java芯片,其低端产品的售价预计不到25美元。

microJava是基于picoJava的微节制器芯片,其芯片面积约为50mm2,用于通信设备和其它嵌入式节制设备。Sun公司盼望Java芯片可以成为推动Java成长的主要技巧之一。

您可能还会对下面的文章感兴趣: