JVM入门之Class结构属性表1

电子说

1.3w人已加入

描述

上篇文章提到过在Class结构表中,属性表存在于Class表,字段表和方法表中,是为了 「描述额外的信息」

❝属性表在《JAVA虚拟机规范》中并没有像其他数据一样做严格的限制,我们甚至可以自己实现一个编译器往Class结构的属性表中注入额外的属性信息,虚拟机运行时会忽略掉它识别不了的属性。

属性表属性总览

这张图中按Class结构,字段表,方法表这三个维度进行了区分标注,将 「三者共有的属性」 提取到最顶部的 「黄色椭圆」 中, 「蓝色」 代表各自属性表 「额外用到的属性」「红色」 代表 「Code属性中引用的其他属性的集合」JVM

引自《深入理解JAVA虚拟机》,读者也可以看这下面的两张图:JVMJVM

属性结构

JVM首先表结构中的前两个字节说明该属性是叫什么名字,也就是什么类型的属性,最终指向常量池中的CONSTANT_Utf8_info类型的常量。

❝eg:Code,ConstantValue,SourceFile。。。等

接着用四个字节描述属性值的长度,也就是说明属性值所占用的字节数;

❝除了第一个属性名称信息和该属性描述的属性长度,其他的就是属性值了,因此该值(属性值长度)固定为 整个属性表长度-6个字节

最后列出属性信息,有多少属性信息呢?前四个字节已经列出了这个属性包含多少个属性,因此最后描述各个属性的信息。

前两个属性是所有属性都共有的,之后就不进行讲解了。

常见属性

Code

❝只有方法内有方法体的方法表才会有这项属性,像抽象方法,非defult接口方法是没有这个属性的(没有方法体)


「该属性用于存放 操作数栈最大深度, 本地变量表最大占用存储空间, 方法中Catch块定义的异常类型和数量, 编译后方法体的字节码指令和指令长度, 还有其他属性」


首先先看下Code属性表的结构:JVM


1.「max_stack操作数栈最大深度」

先看下之前的这篇文章,Java程序运行是基于栈的操作,就是说的该项属性。

通过指令从本地变量表中拿数据放到栈顶;将数据从栈顶保存到本地变量中;对栈顶两个值进行运算后将结果压入栈顶;将栈顶的值作为返回结果return.....等等这些都是通过操作数据结构栈来完成的。

❝这项属性描述了方法中操作数栈的最大深度,虚拟机运行时会根据这项属性来分配栈帧中操作数栈的最大深度。


2.「max_locals局部变量表所需空间」

局部变量表最大占用的存储空间,存储的单位用的是Slot(变量槽),一个 Slot占用空间大小为32位。

存储范围:比如方法的参数,Catch块中定义的异常类型,方法体中定义的局部变量。

❝对于方法参数来说,根据实例方法(通过对象才能访问)和静态方法(通过类名就可以直接访问)又有不同;实例方法的参数中第一个是this,该变量会在编译时加入,而静态方法则没有这个变量。

存储空间:对于小于32位的数据类型用一个变量槽,大于32位的用多个变量槽存储(比如小于64位的数据类型double和long用两个变量槽存储)。优化:对变量限定作用域,如果变量超出了作用域范围,那么存储该变量的Slot进行存储其他的变量,也就是重用变量槽。

❝根据同时生存的最大局部变量数量和类型计算出max_locals的大小。


3.「code_length,code属性用于表述方法体编译后的字节码指令长度和字节码指令流」

❝字节码指令流,一个字节代表一条指令,即每条指令就是一个u1类型的单字节;u1数据类型取值范围是0X00~0XFF,对应十进制为0到255。即u1可以表达256条指令,目前使用的大约只有200条

❝方法体中不允许超过65535条字节码指令,如果超出了编译器拒绝编译;但是code_length用的是u4长度值,可以达到2的32次幂,相当于指令长度只用了一半(u2长度)。


4.「exception_table_length,exception_table用于描述方法块中Catch块定义的异常数量和类型」

❝如果方法体内部没有catch块则length为0,后面的字节不描述exception_table

JVM

在这里插入图片描述

❝Exception table:

from to target type

0 5 10 Class java/lang/Exception

0 5 21 any

10 16 21 any


Exceptions

该属性和上面提到的exception_table描述的信息不一样,exception_table是描述方法体中Catch块中定义的异常数量和类型;而该项属性是描述方法throws的异常数量和类型,通俗来说就是调用该方法需要catch的异常,也叫作受查异常。

❝因此上面的excepitons_table描述方法体内部Catch的异常,Exceptions描述方法抛出的异常

结构:JVM


LineNumberTable

❝用于描述Java代码行号和字节码行号的对应关系,该项属性可选择是否输出

❝用处:当执行某段字节码指令抛出异常时可以根据这个对应关系,提示开发者Java代码对应的行号。

结构JVM


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分