类文件结构的故事(三)

周志明老师的《深入理解java虚拟机》

文章目录

    • Code 属性


Code 属性

之前说到方发表的时候,提到方法体被放在方法表的属性集合里面的 Code 属性中。

不是每一个方法表都必须有 Code 属性,比如 接口抽象类方法 就不需要有 Code 属性。

Code 属性表结构如下:

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 max_stack 1
u2 max_locals 1
u4 code_length 1
u1 code code_length
u2 exception_table_length 1
exception_info exception_table exception_table_length
u2 attribute_count 1
attribute_info attributes attributes_count
  • attribute_name_index 索引指向常量池中的一个 CONSTANT_Utf8_info表 ,内容固定为属性的名字 Code

  • attribute_length 属性值的长度,由于 attribute_lengthattribute_name_index 一种占用 6u2 和 u4) 个字节,所以属性 的长度是整个属性 的长度减去6

  • max_stack 操作数栈的最大深度。32 位的数据占 1 个栈深度,64 位的数据占 2 个栈深度。

  • max_locals 局部变量表所需的最大空间。单位是字宽 Solt,是 JVM 为局部变量分配内存的最小单位。其中对于 32 位数据类型占用 1slot64 为位数据类型占用 2Slot 。其中对象的引用,占一个 slot 32位虚拟机中,64 位虚拟机可能不一样,看是否开启对象指针压缩)

    局部变量包括方法中的定义的变量,方法中捕捉异常 catch 中的参数、还有方法本身的参数,尤其是是实例方法,要注意有一个默认的 thisthisjava 代码很重要,但是实现起来很精巧,在编译的时候,编译器将其对 this 的访问,编译为对方法第一个参数的访问,然后在 JVM 调用方法的时候,传入一个指向当前对象实例的局部变量 。

    因此,实例方法的局部变量表的第一个 Slot 槽位,都是 this

    还有并不是申请多少个变量,然后计算下 slot 就是 max_locals 的值,存在复用的情况,比如有的变量生命周期结束的早,那么它之前占用的空间,就会被重复使用,因此,这里是编译器根据 作用域 算出 max_locals 的值。

  • code_length 代表方法体编译以后的字节码指令长度,虽然是个 u4 类型,占用 4 个字节,虽然可以存储 232 -1 。但是虚拟机规范中有明确限制一个方法不能超过 65535 条字节码指令。 一般不会有方法能这么长,为难编译器,但是 JSP 有时候会将整个页面内容和输出信息放到一个方法里面,导致编译失败。

  • code 代表字节码指令,是个 u1 类型,也就是每个指令用一个字节表示,单个字节最大可以 28 = 256 。所以一共有 256 条指令,JVM 目前已经使用了 200 多条指令。

博客停更一年,准备考研 ,see u again -2020年3月7日13:17:30

你可能感兴趣的:(深入理解,java,虚拟机,读书笔记)