一、JVM语言无关性
1.以字节码为基础(Class文件为一组以8位字节为基础单位的二进制流),JVM与Class文件关联,而非与Java语言关联
2.代码编译从本地码(Native Code)转为字节码:本地机器码,依赖于OS,不具备跨平台特性
二、Class文件
Class文件中只有两种数据类型:无符号数和表
- 无符号数:u1、u2、u4、u8,可以用来描述数字、索引引用、数量值或者字符串值
- 表:多个无符号数或者其他表构成的复合数据类型,表一般以_info结尾
1.魔数字与版本号
- 唯一目的:确定这个文件是否是能被虚拟机接受的Class文件
- 魔数:0xCAFEBABE
- 次版本号
- 主版本号
2.常量池:Class文件中的资源仓库
constant_pool_count:从1开始计数,0表示不引用常量池项目
存放两类变量:
- 字面值:类似Java语言常量,如文本字符串、声明为final的常量值
- 符号引用:
a.类和接口的全限定名
b.字段的名称和描述符
c.方法的名称和描述符
常量池中的每一项常量都是一个表,第一位为u1类型的标志位,取值如下:
- 每一项常量中可能有name_index指向常量值得其他项
- 有些常量如“<init>”、()V等会被Class文件中的field_info、method_info、attribute_info引用
3.访问标志:用于标志类或者接口的访问信息
4.类索引、父类索引与接口索引集合:确定类的继承层次关系
- 类引用、父类引用指向一个类型为CONSTANT_Class_info,通过它可以在常量池找到全限定名字符串
5.字段表集合:用于描述接口或者类中声明的变量,包括类变量(静态变量)与实例变量
字段表结构如下:
6.方法表集合
attribute_info:存放编译好的方法代码Code
7.属性表集合
共21中属性如Code等,属性表结构:
Code:
- max_locals:包含隐藏的this指针,当方法显示没有参数时,此值为1,因为要带入this指针这个参数
- code_length:编译好的字节码长度
- code:字节码指令,1个字节长度,所以最多有256种指令
三、字节码指令
1.字节码与数据类型
- JVM虚拟机指令:字节长度固定(1字节)的操作码+随后的0-多个所需参数
- 优点:
可以获得短小精干的编译代码
- 缺点:
8位,最多256种指令
Class文件格式放弃了编译后代码的操作数长度对其,意味着处理超过一个字节数据时,需要从字节中重建出具体结构的数据,影响性能
- 执行模型伪代码:
do {
自动计算PC寄存器的值加1;
根据PC寄存器的指示位置,从字节码中取出操作码;
if (字节码存在操作数) 从字节码流中取出操作数;
执行操作码所定义的操作;
}while(字节码流长度 > 0)
2.指令
- 加载与储存
- 运算
- 类型转换
- 对象创建与访问
- 操作数栈管理
- 控制转移
- 方法调用与返回
- 异常处理
- 同步