详解 JVM 字节码(Four)

作者: zidea | 来源:发表于2019-05-03 18:12 被阅读5次
jvm
访问标志

访问标志信息包括该 Class 文件是类还是接口,是否被定义成 public,是否是 abstract,如果是类,是否声明为 final。


访问标志表

通过名字大家都很清楚是什么意思。

  • ACC_SUPER 子类调用父类一些相关方法

看一看我们字节码中是 00 21(访问标识),表中并没有 21 对应标志。在访问标志可以两个标志的组合。其实这里 00 21 是 ACC_PUBLIC 和 ACC_SUPER 的组合。

public class Tut
类名称
00 05

这里是一个常量池中索引对应

 #5 = Class              #32            // com/zidea/Tut

对应当前类名称

父类名称
00 06

对应父类名字

 #6 = Class              #33            // java/lang/Object
接口
00 00

表示当前类实现的接口数量,这里为 0 也就是没有实现接口,接口表也不会出现。

字段
00 02

说明我们 Tut 有两个字段

    private String title = "basic";
    private int courses = 10;

下表表示我们字段表每一个字段的信息


字段表集合

表示字段数量,表示字段表的,所谓字段表用于描述类和接口中声明的变量(包括类级别变量和实例变量,但不包括方法内局部变量)

  • 并不是没有字段都有attributes_count属性,如果其值为 0,没有attribute_info也就不存在。
private String title = "basic";

00 02 (access_flags) 表示私有的
00 07 (name_index) #7 = Utf8 title
00 08 (descriptor_index) #8 = Utf8 Ljava/lang/String;
00 00 (attributes_count) 因为是 0 所以不会出现没有attribute_info

private int courses = 10;

这个大家自己做吧。根据规则来推测这个字段的信息
00 02
0 09
00 0A
00 00

方法
{
    "method_info":{
        "access_flag":"方法标志",
        "name_index":"方法名称",
        "descriptor_index":"方法描述,方法长啥样,返回值和参数",
        "attributes_count":"属性表长度",
        "attribute_info":[
            {
                "attribute_name_index":"属性名索引",
                "attribute_length":"",
                "info":[

                ]
            }
        ]
    }
}

通过一个 json 来表示这部分字节码的结构。

00 05

表示有 5 个方法,随后继续进行分析。来看一看方法表

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getCourses() {
        return courses;
    }

    public void setCourses(int courses) {
        this.courses = courses;
    }

在 Tut 类中定义了 4 个 settergetter方法,再加上编译默认生成空构造方法就一共 5 个方法。

方法表结构

00 01 (access_flags) 表示共有方法 ACC_PUBLIC
00 0B (name_index) #11 = Utf8 <init> 表示函数名字,一看到 init 就知道这个是函数构造方法。
00 0C (descriptor_index) #12 = Utf8 ()V 用于描述函数结构,也就是函数具体样子。
00 01(attributes_count) 表示有一个属性
我们需要了解一些方法属性结构attributes_count
00 0D (13 )(attribute_name_index)对应常量池 #13 = Utf8 Code

  • Code 表示这个方法执行的代码
    00 00 00 43 (67) (attribute_length) 表示会占据 67 字节做 code 指令,也就是函数体的内容。
    00
    JVM预定义了部分 attribute,编译器自己也可以实现自己的 attribute 写入 class 文件,供运行时使用。
    看看 code 这部分的结构,
    "code_attribute":{
        "attribute_name_index":"u2",
        "attribute_length":"u4",
        "max_stack":"u2",
        "max_locals":"u2",
        "code_length":"u4",
        "code[code_length]":"u1",
        "exception_table_length":"u1",
        "exception_table[exception_table_length]":[
            {
                "start_pc":"u2",
                "end_pc":"u2",
                "handler_pc":"u2",
                "catch_type":"u2"
            }
        ],
        "attribute_count":"u2",
        "attribute_info":[
            
        ]

    }

这是一个很重要部分内容,所以需要花时间和精力在上面

  • attribute_length :表示 attribute 所包含的字节数,不包含 attribute_name_index 和 attribute_length 字段
  • max_stack : 这个方法运行的任何时刻所能达到的操作数栈的最大深度
  • max_locals : 方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量
  • code_length : 方法所包含的字节码的字节数以及具体的指令码
  • exception_table : 存放异常处理信息
  • start_pc 和 end_pc 表示在 code 数组中从 start_pc 到 end_pc 处的指令抛出的异常会由这个表项进行处理
  • handler_pc 表示处理异常的代码的开始处。catch_type 表示会被处理的异常类型。

00 02 (max_stack)
00 01 (max_locals)
00 00 00 11(code) 长度 17

为了便于我们查看字节码引入一个 jclasslib 来更直观查看字节码,可以独立安装也可以安装 idea 的插件,这里我用的是插件


jclasslib 安装 启用查看字节码视图 打开字节码窗口

附加属性

  • LineNumberTable:表示 code 数组中的字节码和 java 代码行数之间的关系。这个属性可以用于在调试的时候定位代码行数。


    LineNumberTable
属性

相关文章

  • 详解 JVM 字节码(Four)

    访问标志 访问标志信息包括该 Class 文件是类还是接口,是否被定义成 public,是否是 abstract,...

  • JVM

    JVM 基础-类字节码详解 多语言编译为字节码在 JVM 运行 Java 字节码文件-- Class文件的结构属性...

  • JVM知识精粹

    1.jvm执行字节码文件 流程:jvm通过类加载器加载字节码文件----字节码校验器---翻译字节码(解释执行,反...

  • Java并发机制的底层原理

    Java程序执行:Java代码→Java字节码→字节码被类加载器加载到JVM里,JVM执行字节码→转化为汇编指令在...

  • Java并发机制的底层实现原理

        Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为...

  • 详解 JVM 字节码 (1)

    在开始分析 class 字节码前我们先补一补一些基础知识,帮助我们更好地了解 jvm 是如何执行字节码的。大家可能...

  • 详解 JVM 字节码(3)

    版本信息 上一次我们分析前 4 个字节为魔数,继续向下数 4 字节为版本号信息(前两个字节表示此版本号,后两个字节...

  • 详解 JVM 字节码(2)

    什么是字节码,为什么需要字节码编译 JVM 编译成机器码, 我们看一看 Java 编译过程 java 源码 编译为...

  • 详解 JVM 字节码(8)

    字节码的执行方式,程序执行有两种是编译执行和解释执行,JIT 编译产生本地代码生成机器码来执行。现在的 JVM 解...

  • 详解 JVM 字节码(5)

    今天进入最关键也是最重要部分方法表,也是有一定难度。 定义方法访问标记00 01 :表示一个 public 方法,...

网友评论

    本文标题:详解 JVM 字节码(Four)

    本文链接:https://www.haomeiwen.com/subject/wqwonqtx.html