本文在研究kaffe的基础上,吸收kaffe虚拟机的主要思想,用C语言作为开发语言,采用了及时编译器作为执行引擎,实现了一种Windows平台下的Java虚拟机。
引言
Java虚拟机本质是就是一个程序,当它在命令行上启动的时候,就开始执行保存在某字节码文件中的指令。Java语言的可移植性正是建立在Java虚拟机的基础上。任何平台只要装有针对于该平台的Java虚拟机,字节码文件(.class)就可以在该平台上运行。这就是“一次编译,多次运行”。
kaffe虚拟机的简要分析 kaffe虚拟机采用了模块化的程序设计思想,它由多个独立的子系统组成。从功能模块上来分它主要分为:虚拟机总体驱动模块,类装载器模块,类执行模块, 数据区管理模块,内存管理模块,本地支持模块等等。kaffe虚拟机简要的程序流程图如图1所示。
图1 kaffe虚拟机简要的程序流程图
Java虚拟机的实现 Java 源程序的执行过程为: Java源程序(.java)经过Java编译器编译生成字节码文件(.class),然后由类装载器将字节码文件装载到方法区中,然后进行连接验证,由Java虚拟机读取字节码,转换为特定平台的指令,并且在对应的CPU中执行。
本实现中采用的流程框架如下图所示:
图2 本实现的主要框架
1、类装载、连接及初始化
类文件包括:魔数(magic),次、主版本号,常量池,类或接口访问修饰符,常量池索引(this_class和super_class),接口表,域表,方法表,类或接口的属性信息。其中最复杂的内容是常量池,它类似于传统语言编译过程中用到的符号表。
从原始的class文件到可以被Java虚拟机执行的内部数据格式,需要经过装载、连接和初始化这3个阶段。
装载是将class文件通过类装载器装载到在逻辑上被称为方法区的内存单元中的过程。
连接又分为三个步骤:验证,准备和解析。验证是对字节码的验证,可根据具体情况来确定被装载的类是否符合Java虚拟机规范中规定的class文件格式,并确保它不会破坏Java虚拟机的完整性。包括(1)类装载过程中的验证; (2) 检查class文件内部的连贯性,一旦发现class文件格式存在一处错误,则抛出VerifyError异常或ClassFormatError异常。确保每个final类不含有子类,final方法不能被覆盖,以及常量池中所有的域引用和方法引用有有效的名字和类型描述符号;(3) 对字节码流使用一个数据流分析器进行验证。准备步骤的任务是创建域表,并设置域初值。解析步骤是将类中的常量池中的类、接口、字段和方法的符号引用替换成直接引用,以达到更快地访问数据的目的。
在初始化阶段,Java虚拟机设计者需要将类变量赋予正确的初始值。
class文件经过上述三个阶段的处理,虚拟机就获得了该类的所有信息并且表示成能够容易操作的内部数据格式,从而为方法的运行作好了充分的准备。