Class文件中的方法和字节码同步指令
2020-10-03 本文已影响0人
雁阵惊寒_zhn
Class文件中的方法
Class文件是一组以8个字节为基础单位的二进制流。
Code属性(方法体中执行的Java代码)——Class文件中最重要的一个属性
Java程序中的信息可以分为代码和元数据。代码就是方法体中执行的Java代码,Code属性就是描述这部分信息。余下的信息都是元数据,包括类、字段、方法定义等其他信息。
Code属性中包含两个重要的2个字节长度的数字属性,max_stack和max_locals。max_stack表示操作数栈(Operand Stack)深度的最大值;max_locals代表了局部变量表所需的存储空间,单位是虚拟机为局部变量分配内存使用的最小单位变量槽(Slot)。这两个数值直接决定一个方法栈帧所耗费的内存空间。为了节约空间,变量槽是可以重用的,当代码执行超出一个局部变量的作用域时,这个局部变量所占的变量槽可以被其他局部变量重复使用。
Java方法中的this引用
在任何实例方法中都可以通过"this"访问到当前方法所属的对象。这是在Java编译的时候,把对this的访问作为对一个普通形参的访问,虚拟机执行方法时自动传入此参数。局部变量表会留出第一个变量槽存放对象实例的引用this,其他实例方法参数从变量槽1开始。
字节码指令
Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需的参数(称为操作数,Operand)构成。
Java虚拟机采用面向操作数栈架构,字节码指令的执行是基于操作数栈的。
字节码指令种类
- 加载和存储指令
将数据在栈帧中的局部变量表和操作数栈之间进行传输主要由加载和存储指令进行操作。除此之外,还有如访问对象字段或数组元素的指令也会向操作数栈传输数据。 - 运算指令
对操作数栈上两个值进行运算,并且把结果重新存入到操作数栈顶。 - 类型转换指令
- 对象创建与访问指令
- 控制转移指令
- 方法调用和返回指令
- 异常处理指令
- 同步指令
同步指令
Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步。两种同步结构都使用管程(Monitor,或直接称为锁)来实现。
- 方法级的同步是隐式的,无须通过字节码指令来控制,实现在方法调用和返回中。在Class文件中同步的方法用ACC_SYNCHRONIZED标识,方法调用时会先检查是否设置了这个字段,如果存在,执行线程需要先成功持有管程,才能执行方法。正常退出方法或者抛出异常都会自动释放管程。
- 同步代码块通常是synchronized语句块,Java虚拟机的指令集中有monitorenter和monitorexit两条指令支持关键字synchronized语义。两条指令之间的部分就是同步的代码块逻辑的字节码指令。