Java 实现简易 JVM
github 地址
主要模块和样例(github 有每个模块样例):
- 读取并解析 class 文件,如 String、Thread 等类(支持 jdk8 及以下)
- 取 opcode,解释执行程序。循环运算,入栈出栈
- 方法调用(静态方法、构造方法、实例方法(支持继承多态))
- 数组
- 字符串和字符串数组
- 调用本地方法
- gc(标记清除算法)
目录结构
com\zvm
basestruct\ #读取字节码为内存中 ClassFile 时的基本数据结构
classfile\ #类解析相关
attribute\ #属性表:jdk8 中的 23 种属性
constantpool\ #常量池:jdk8 中 10 种常量类型
ClassFile.java #解析后的 class 文件
cp_info.java #ClassFile 中的常量池表示
field_info.java #ClassFile 中的字段表示
IOUtils.java #解析字节码的工具类
method_info.java #ClassFile 中的方法表示
ZvmClassLoader.java #待重构
draft\
gc\
GC.java #GC 类,目前只有标记清除算法
interpreter\
CallSite.java #调用方法时的入口
CodeUtils.java #控制 pc 的工具类
Descriptor.java #方法调用时,表示返回数据和入参结构
Interpreter.java #取 opcode 并执行的类
Opcode.java #指令
Ref.java #表示 methodRef 或 fieldRef:含类名、描述符、方法名 /字段名
jnative\java\lang\ #预留实现本地方法
memory\
ArrayFields.java #保存堆中的数组
JavaHeap.java #表示堆,对象和数组都分配在这
MethodArea.java #方法区
ObjectFields.java #表示堆中的对象
runtime\ #运行时数据
struct\ #一些基本数据结构
JavaClass.java #运行时表示:ClassFile 的入口,加一些类的信息
JavaFrame.java #运行时表示:一个方法所用的帧
JThread.java #运行时表示:一个线程(目前未实现多线程)
LocalVars.java #运行时表示:帧中的局部变量表
OperandStack.java #运行时表示:帧中的操作数栈
RunTimeEnv.java #运行时的环境,包括 JavaHeap、MethodMrea 等
StaticVars.java #JavaClass 中的静态字段分配内存
ThreadStack.java #线程栈:运行时,方法调用帧由底至上组成线程栈
utils\
TypeUtils.java #类型转换工具类
Vars.java #供 LocalVars、LocalVars、ObjectFields 继承使用
Cmd.java #解析命令行
JavaMain.java #启动入口类,含 main 方法
ZVM.java #表示虚拟机
已实现指令(绝大部分实现了)
- 加载(load)、存储(store)指令,将数据在局部变量表和操作数栈中来回传输
- 运算指令
- 类型转换指令
- 对象创建和操作
- 操作数栈管理
- 控制转移
- 方法调用和返回
引用和参考
文档、书籍参考
- java 虚拟机规范
- 《自己动手写 Java 虚拟机》
- java 虚拟机规范(java se7)中文版
- java 虚拟机规范(java se8)中文版
- 周志明的《深入理解 java 虚拟机》
代码参考
工具