background image

之甚少。Java 虚拟机支持大约 248 个字节码。每个字节码执行一种基本的 CPU 运算,例如,把一个整数 
加到寄存器,子程序转移等。Java 指令集相当于 Java 程序的汇编语言。
Java 指令集中的指令包含一个单字节的操作符,用于指定要执行的操作,还有 0 个或多个操作数,提供操
作所需的参数或数据。许多指令没有操作数,仅由一个单字节的操作符构成。
虚拟机的内层循环的执行过程如下: 
do{ 
取一个操作符字节; 
根据操作符的值执行一个动作; 
}while(程序未结束)
由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。指令中操作数的
数量和大小是由操作符决定的。如果操作数比一个字节大,那么它存储的顺序是高位字节优先。例如,一
个 16 位的参数存放时占用两个字节,其值为:
第一个字节*256+第二个字节字节码。
指令流一般只是字节对齐的。指令 tableswitch 和 lookup 是例外,在这两条指令内部要求强制的 4 字节
边界对齐。
对于本地方法接口,实现 JVM 并不要求一定要有它的支持,甚至可以完全没有。Sun 公司实现 Java 本
地接口(JNI)

 

是出于可移植性的考虑,当然 我们也可以设计出其它的本地接口来代替 Sun 公司的 JNI。

但是这些设计与实现是比较复杂的事情,需要确保垃圾回收器不会将那些正在被本地方法调用的对象 
释放掉。
Java 的堆是一个运行时数据区,类的实例(对象)从中分配空间,它的管理是由垃圾回收来负责的:不给程
序员显式释放对象的能力。Java 不规定具体使用的垃圾回收算法,可以根据系统的需求使用各种各样的
算法。
Java 方法区与传统语言中的编译后代码或是 Unix 进程中的正文段类似。它保存方法代码(编译后的
java 代码)和符号表。在当前的 Java

 

实现 中,方法代码不包括在垃圾回收堆中,但计划在将来的版本中实

现。每个类文件包含了一个 Java 类或一个 Java

 

界面的编译后的代码。可以说类文件是 Java 语言的执

行代码文件。为了保证类文件的平台无关性,Java 虚拟机规范中对类文件的格式也作了详细的说明。其
具体细节请参考 Sun 公司的 Java 虚拟机规范。
Java 虚拟机的寄存器用于保存机器的运行状态,与微处理器中的某些专用寄存器类似。Java 虚拟机的寄
存器有四种:

1.

pc: Java 程序计数器;

2.

optop: 指向操作数栈顶端的指针;

3.

frame: 指向当前执行方法的执行环境的指针;。

4.

vars: 指向当前执行方法的局部变量区第一个变量的指针。

在上述体系结构图中,我们所说的是第一种,即程序计数器,每个线程一旦被创建就拥有了自己的程序
计数器。当线程执行 Java 方法的时候,它包含该线程正在被执行的指令的地址。但是若线程执行的是
一个本地的方法,那么程序计数器的值就不会被定义。
Java 虚拟机的栈有三个区域:局部变量区、运行环境区、操作数区。
局部变量区
每个 Java 方法使用一个固定大小的局部变量集。它们按照与 vars 寄存器的字偏移量来寻址。局部变量
都是 32

 

位的。长整数和双精度浮点数占据了两 个局部变量的空间,却按照第一个局部变量的索引来寻

址。(例如,一个具有索引 n 的局部变量,如果是一个双精度浮点数,那么它实际占据了索引 n 和 n+1 所代 
表的存储空间)虚拟机规范并不要求在局部变量中的 64 位的值是 64 位对齐的。虚拟机提供了把局部变
量中的值装载到操作数栈的指令,

 

也提供了把操作数栈中的 值写入局部变量的指令。

运行环境区
在运行环境中包含的信息用于动态链接,正常的方法返回以及异常捕捉。
动态链接
运行环境包括对指向当前类和当前方法的解释器符号表的指针,用于支持方法代码的动态链接。方法的
class

 

文件代码在引用要调用的方法和要访问的变 量时使用符号。动态链接把符号形式的方法调用翻译