zoukankan      html  css  js  c++  java
  • JVM字节码

    JVM字节码
    1、通过javap命令查看class文件的字节码内容    
    首先,看下面简单的代码:

    public class Test1 {
    public static void main(String[] args) {
    int a = 2;
    int b = 5;
    int c = b - a;
    System.out.println(c);
    }
    }

    通过javap命令查看class文件中的字节码:

    javap -v Test1.class > Test1.txt 
    其中, 可能的选项包括:
        ‐help ‐‐help ‐?                     输出此用法消息
        ‐version                         版本信息
        ‐v ‐verbose                     输出附加信息
        ‐l                                 输出行号和本地变量表
        ‐public                         仅显示公共类和成员
        ‐protected                         显示受保护的/公共类和成员
        ‐package                         显示程序包/受保护的/公共类和成员 (默认)
        ‐p ‐private                     显示所有类和成员
        ‐c                                 对代码进行反汇编
        ‐s                                 输出内部类型签名
        ‐sysinfo                         显示正在处理的类的系统信息 (路径, 大小, 日期, MD5 散列)
        ‐constants                         显示最终常量
        ‐classpath <path>                 指定查找用户类文件的位置
        ‐cp <path>                         指定查找用户类文件的位置
        ‐bootclasspath <path>            覆盖引导类文件的位置  

    输出的字节码为:

    Classfile /root/study/workspace/Test1.class
    Last modified Aug 6, 2019; size 579 bytes
    MD5 checksum a96ef22100a65dc41cf1fda3e995d015
    Compiled from "Test1.java"
    public class com.lailai.jvm.Test1
    minor version: 0
    major version: 52
    flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
    #1 = Methodref #5.#23 // java/lang/Object."<init>":()V
    #2 = Fieldref #24.#25 // java/lang/System.out:Ljava/io/PrintStream;
    #3 = Methodref #26.#27 // java/io/PrintStream.println:(I)V
    #4 = Class #28 // com/lailai/jvm/Test1
    #5 = Class #29 // java/lang/Object
    #6 = Utf8 <init>
    #7 = Utf8 ()V
    #8 = Utf8 Code
    #9 = Utf8 LineNumberTable
    #10 = Utf8 LocalVariableTable
    #11 = Utf8 this
    #12 = Utf8 Lcom/lailai/jvm/Test1;
    #13 = Utf8 main
    #14 = Utf8 ([Ljava/lang/String;)V
    #15 = Utf8 args
    #16 = Utf8 [Ljava/lang/String;
    #17 = Utf8 a
    #18 = Utf8 I
    #19 = Utf8 b
    #20 = Utf8 c
    #21 = Utf8 SourceFile
    #22 = Utf8 Test1.java
    #23 = NameAndType #6:#7 // "<init>":()V
    #24 = Class #30 // java/lang/System
    #25 = NameAndType #31:#32 // out:Ljava/io/PrintStream;
    #26 = Class #33 // java/io/PrintStream
    #27 = NameAndType #34:#35 // println:(I)V
    #28 = Utf8 com/lailai/jvm/Test1
    #29 = Utf8 java/lang/Object
    #30 = Utf8 java/lang/System
    #31 = Utf8 out
    #32 = Utf8 Ljava/io/PrintStream;
    #33 = Utf8 java/io/PrintStream
    #34 = Utf8 println
    #35 = Utf8 (I)V
    {
    public com.lailai.jvm.Test1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
    stack=1, locals=1, args_size=1
    0: aload_0
    1: invokespecial #1 // Method java/lang/Object."<init>":()V
    4: return
    LineNumberTable:
    line 3: 0
    LocalVariableTable:
    Start Length Slot Name Signature
    0 5 0 this Lcom/lailai/jvm/Test1;
    
    public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
    stack=2, locals=4, args_size=1
    0: iconst_2
    1: istore_1
    2: iconst_5
    3: istore_2
    4: iload_2
    5: iload_1
    6: isub
    7: istore_3
    8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
    11: iload_3
    12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
    15: return
    LineNumberTable:
    line 6: 0
    line 7: 2
    line 8: 4
    line 9: 8
    line 10: 15
    LocalVariableTable:
    Start Length Slot Name Signature
    0 16 0 args [Ljava/lang/String;
    2 14 1 a I
    4 12 2 b I
    8 8 3 c I
    }
    SourceFile: "Test1.java"

    输出内容大致分为4部分:

    第一部分,显示了生成这个class的java源文件、版本信息、生成时间等。
    第二部分,显示了该类中所涉及到常量池,共35个常量。
    第三部分,显示了该类的构造器,编译器自动插入的。
    第四部分,显示了main方法的信息。(需要重点关注)
    2、常量池
    官网文档:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4-140


    3、描述符
    3.1、字段描述符
    官网文档:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2

    英文的看不懂大佬我给你们中文的


    3.2、方法描述符
    官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3
    示例:
    The method descriptor for the method:

    Object m(int i, double d, Thread t) {...}

    is

    (IDLjava/lang/Thread;)Ljava/lang/Object


    可以看到括号内为方法的参数,括号外面为方法的返回值。

    I 表示 int类型
    D 表示double类型
    Ljava/langThread; 表示对Thread的引用
    Ljava/lang/Object; 表示对Object的引用
    4、解读方法字节码

    public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V    //方法描述,V表示该方法的返回值为void
    flags: ACC_PUBLIC, ACC_STATIC    //方法修饰符,public、static的
    Code:
    stack=2, locals=4, args_size=1    //stack=2,操作栈大小为2、locals=4,本地变量大小,args_size=1,参数的个数
    0: iconst_2    //将数字2压入操作栈,位于栈的最上面
    1: istore_1    //从操作栈中弹出一个元素(数字2),放入本地变量表中,位于下标为1的位置(下标为0的是this)
    2: iconst_5    //将数字5压入操作栈,位于栈的最上面
    3: istore_2    //从操作栈中弹出一个元素(数字5),放入本地变量表中,位于下标为2的位置
    4: iload_2    //将本地变量表中下标为2的位置的元素压入操作栈(5)
    5: iload_1    //将本地变量表中下标为1的位置的元素压入操作栈(2)
    6: isub    //操作栈中的2歌数字相减
    7: istore_3    //将相减的结果压入到本地变量表中,位于下标为3的位置
    //通过#2号在Constant pool中找到对应的常量,即可找到对应的引用
    8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
    11: iload_3    //将本地变量表中下标为3的位置的元素压入操作栈(3)
    //通过#3号在Constant pool中找到对应的常量,即可找到对应的引用,进行方法调用
    12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
    15: return    //返回
    LineNumberTable:    //行号的列表
    line 6: 0
    line 7: 2
    line 8: 4
    line 9: 8
    line 10: 15
    LocalVariableTable:    //本地变量表
    Start Length Slot Name Signature
    0 16 0 args [Ljava/lang/String;
    2 14 1 a I
    4 12 2 b I
    8 8 3 c I
    }
    SourceFile: "Test1.java"


    5、图解

     

     

     

  • 相关阅读:
    OI无关--关于侧边栏
    Codeforces Round #528 div1
    BZOJ 3531: [Sdoi2014]旅行
    BZOJ 4538: [Hnoi2016]网络
    Codeforces Round #527 (Div. 3)
    Avito Cool Challenge 2018
    Educational Codeforces Round 56 (Rated for Div. 2)
    Codeforces Round #526 (Div. 1)
    2018-2019 Russia Open High School Programming Contest (Unrated, Online Mirror, ICPC Rules, Teams Preferred)
    Codeforces Round #525 (Div. 2)
  • 原文地址:https://www.cnblogs.com/rzbwyj/p/12462374.html
Copyright © 2011-2022 走看看