第8章 虚拟机字节码执行系统
6.4字节码指令简介 Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成。由于Java虚拟机采用面向操作数栈而不是寄存器的架构,所以大多数的指令都不包含操作数,而只有一个操作码。 6.4.1 字节码与数据类型 Java虚拟机的指令集中,大多数的指令都包含了其操作数所对应的数据类型信息。 如果每一种与数据类型相关的指令都支持Java虚拟机所有运行时数据类型的话,那指令的数量恐怕就会超出一个字节所能表示的数量范围了 前面的被系统吞了 之后再补上 第8章 虚拟机字节码执行系统 8.1概述 8.2 运行时栈帧结构 8.2.1 局部变量表 是一组变量存储空间,用于存放方法参数和方法内部定义的局部变量。 用于存放方法参数和方法内部定义的局部变量。 容量以变量槽(Variable Slot)为最小单位,虚拟机规范中并没有明确指明一个Slot应占用的内存空间大小,知识很有导向性地说道每个Slot都应该能存放一个boolean、byte、char、short、int、float、reference或returnAddress类型的数据。 只要保证计时在64位虚拟机中使用了64位的物理内存空间去实现一个Slot,虚拟机仍要使用对齐和不败的手段让Slot在外观上看起来与32位虚拟机中的一致。 Java中占用32位以内的数据类型有boolean、byte、char、short、int、float、reference和returnAddress8种类型。(Java语言与Java虚拟机种的剧本数据类型是存在本质差别的)。reference类型表示对一个对象实例的引用。虚拟机规范没有指明长度和结构。但需要做到如下两点: 从引用中直接或间接地查找到对象在Java堆中的数据存放的起始地址索引; 引用中直接或简介地查找到对象所属数据类型在方法区中地存储的类型信息,否则无法实现Java语言规范中定义的语法约束。 returnAddress类型目前已经很少见了,为字节码指令jsr、jsr_w和ret服务的,指向一条字节码指令的地址,很古老的Java虚拟机曾经使用这几条指令来实现异常处理,现在已经由异常表替代。 Java中明确的64位的数据类型只有long和double两种。分割存储的做法与“long和double的非原子性协定”类似。 但在局部变量表中不会引起数据安全问题(线程私有)。 索引定位。访问32位数据类型的变量,索引n就代表了使用第n个Slot。64位则会同时使用n和n+1两个Slot。对于两个相邻的共同存放一个64位数据的两个Slot,不允许采用任何方式单独访问其中的某一个。 在方法执行时,如果执行的实例(非static),局部变量表中第0位索引的Slot默认时用于传递方法所属对象实例的引用,在方法中可以通过关键字“this”来访问到这个隐含的参数。 为了尽可能节省栈帧空间,局部变量表中的Slot是可以重用的,方法中定义的变量,其作用域并不一定会覆盖整个方法体。副作用:某些情况下会直接影响到GC。 实例,placeholder能否被回收的根本原因是:局部变量表中的Slot是否还存有关于placeholder数组对象的引用。 局部变量表是GC Roots的一部分。把不用的占用了大量内存的变量手动设置为null值。 但冲编码角度讲,以恰当的变量作用域来控制变量回收时间才是最优雅的解决方法。 ———————————待补充——————————— 局部变量不负初值会编译不通过。