zoukankan      html  css  js  c++  java
  • Java字节码方法表结构深度剖析

    继续上一次【https://www.cnblogs.com/webor2006/p/9459681.html】的字节码分析,这次来分析一下最为复杂的方法表的信息,如下:

    而上一次分析到了属性表的位置在:

    接着来看一下方法表相关的信息:

    所以往下找两个字节:

    因为有一个编译器为其生成的一个构造方法,这时咱们对照着上一次介绍的jclasslib工具来对照一下:

    接着往下则是方法表相关的信息:

    先来看一下表结构:

    也就是说每个方法所对应的方法表结构如上,所以接下来看一下第一个方法的信息,往下数2个字节则是access_flags,如下:

    那它对应哪个访问标志则需要查一下:

    表示是public的方法,接下来四个字节为方法名字和索引和描述符的索引,一起看:

    其对应的常量池信息如下:

    也就是第一个方法是构造方法,接着往下则是方法的属性相关的东东,注意:这个属性跟方法的变量是两码事,如下:

    所以往下数两个字节,看一下方法属性的个数:

    说明有一个方法属性,而往后两个字节对是属性名称索引,如下:

    对应常量池:

    Code属性,对于每一个方法都有一个Code属性,如下:

    {
      public com.jvm.bytecode.MyTest1();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: iconst_1
             6: putfield      #2                  // Field a:I
             9: return
          LineNumberTable:
            line 3: 0
            line 4: 4
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      10     0  this   Lcom/jvm/bytecode/MyTest1;
    
      public int getA();
        descriptor: ()I
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: getfield      #2                  // Field a:I
             4: ireturn
          LineNumberTable:
            line 7: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Lcom/jvm/bytecode/MyTest1;
    
      public void setA(int);
        descriptor: (I)V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=2, args_size=2
             0: aload_0
             1: iload_1
             2: putfield      #2                  // Field a:I
             5: return
          LineNumberTable:
            line 11: 0
            line 12: 5
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       6     0  this   Lcom/jvm/bytecode/MyTest1;
                0       6     1     a   I
    }
    SourceFile: "MyTest1.java"

    其实就是描述了整个方法的Code信息,Code attribute的作用是保存该方法的结构,如所对应的字节码:

    其中attribute_name_index则是属性名的索引,也就是Code,接下来还有一些信息下面来解释一下:

    • attribute_length表示attribute所包含的字节数,不包含attribute_name_index和attribute_length字段。

      说的是什么意思呢?比如attribute_length=50个字节,则是指往后的50个字节则为整个Code属性的信息,所以往后先数4个字节咱们来看一看长度:

      也就是说属性的长度为56,所以往后56个字节则为具体Code属性的信息,如下:

       那咱们来jclasslib中来确认一下是否也是显示的56个字节,如下:

    • max_stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度。

      也就是在上面56个字节从头数2个字节,则是这个操作数栈的最大深度,咱们来看一下:

      也就是最大的深度为2。如javap -verbose所示:

    • max_locals表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量。

      再继续读2个字节:

      也就是局部变量的数目为1,如javap -verbose所示:

    • code_length表示该方法所包含的字节码的字节数以及具体的指令码。具体指令码既是该方法被调用时,虚拟机所执行的字节码。

      也就是占10个字节,所以往后数10个字节:

      其实这10个字节是对应在jclasslib中的代码助记符的信息,如下:

      呃~~助记符能跟字符信息对应上?这不是扯淡么~~其实它们之间是有一些对应关系的,具体怎么对应下回再来探讨。

  • 相关阅读:
    Linux基础知识整理
    小白学习之路,基础四(函数的进阶)
    关于高通量数据格式
    数据库管理系统
    Linux 基本操作
    生信研究内容
    redis6 多线程特性
    Centos8配置NFS4
    关于Mybatis将查询结果中添加常量列并返回
    关于swagger文档的使用方法
  • 原文地址:https://www.cnblogs.com/webor2006/p/9502507.html
Copyright © 2011-2022 走看看