中国建设银行个人网站,建设网站市场细分,全flash网站源码,建设个公司网站需要多少费用目录 2.1 入门
2.2 javap 工具
2.3 图解方法执行流程
1#xff09;原始 java 代码
2#xff09;编译后的字节码文件
3#xff09;常量池载入运行时常量池
4#xff09;方法字节码载入方法区
5#xff09;main 线程开始运行#xff0c;分配栈帧内存
6#xff09;…目录 2.1 入门
2.2 javap 工具
2.3 图解方法执行流程
1原始 java 代码
2编译后的字节码文件
3常量池载入运行时常量池
4方法字节码载入方法区
5main 线程开始运行分配栈帧内存
6执行引擎开始执行字节码
bipush 10
istore_1
ldc #3
istore_2
iload_2
iadd
istore_3
getstatic #4
iload_3
invokevirtual #5
return 2.1 入门
接着上一节研究一下两组字节码指令一个是
//构造方法的字节码指令
public cn.itcast.jvm.t5.HelloWorld();
2a b7 00 01 b1
2a aload_0 加载 slot 0 的局部变量即 this做为下面的 invokespecial 构造方法调用的参数b7 invokespecial 预备调用构造方法哪个方法呢00 01 引用常量池中 #1 项即【 Method java/lang/Object.:()V 】b1 表示返回另一个是 public static void main(java.lang.String[]); 主方法的字节码指令
b2 00 02 12 03 b6 00 04 b1
b2 getstatic 用来加载静态变量哪个静态变量呢00 02 引用常量池中 #2 项即【Field java/lang/System.out:Ljava/io/PrintStream;】12 ldc 加载参数哪个参数呢03 引用常量池中 #3 项即 【String hello world】b6 invokevirtual 预备调用成员方法哪个方法呢00 04 引用常量池中 #4 项即【Method java/io/PrintStream.println:(Ljava/lang/String;)V】b1 表示返回
请参考
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5 2.2 javap 工具
自己分析类文件结构太麻烦了Oracle 提供了 javap 工具来反编译 class 文件
[rootlocalhost ~]# javap -v HelloWorld.class
Classfile /root/HelloWorld.class
Last modified Jul 7, 2019; size 597 bytes
MD5 checksum 361dca1c3f4ae38644a9cd5060ac6dbc
Compiled from HelloWorld.java
public class cn.itcast.jvm.t5.HelloWorld
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 Methodref #6.#21 // java/lang/Object.init:()V
#2 Fieldref #22.#23 //
java/lang/System.out:Ljava/io/PrintStream;
#3 String #24 // hello world
#4 Methodref #25.#26 // java/io/PrintStream.println:
(Ljava/lang/String;)V
#5 Class #27 // cn/itcast/jvm/t5/HelloWorld
#6 Class #28 // java/lang/Object
#7 Utf8 init
#8 Utf8 ()V
#9 Utf8 Code
#10 Utf8 LineNumberTable
#11 Utf8 LocalVariableTable
#12 Utf8 this
#13 Utf8 Lcn/itcast/jvm/t5/HelloWorld;
#14 Utf8 main
#15 Utf8 ([Ljava/lang/String;)V
#16 Utf8 args
#17 Utf8 [Ljava/lang/String;
#18 Utf8 MethodParameters
#19 Utf8 SourceFile
#20 Utf8 HelloWorld.java
#21 NameAndType #7:#8 // init:()V
#22 Class #29 // java/lang/System
#23 NameAndType #30:#31 // out:Ljava/io/PrintStream;
#24 Utf8 hello world
#25 Class #32 // java/io/PrintStream
#26 NameAndType #33:#34 // println:(Ljava/lang/String;)V
#27 Utf8 cn/itcast/jvm/t5/HelloWorld
#28 Utf8 java/lang/Object
#29 Utf8 java/lang/System
#30 Utf8 out
#31 Utf8 Ljava/io/PrintStream;
#32 Utf8 java/io/PrintStream
#33 Utf8 println
#34 Utf8 (Ljava/lang/String;)V
{
public cn.itcast.jvm.t5.HelloWorld();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack1, locals1, args_size1
0: aload_0
1: invokespecial #1 // Method java/lang/Object.
init:()V
4: return
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/itcast/jvm/t5/HelloWorld;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack2, locals1, args_size1
0: getstatic #2 // Field
java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String hello world
5: invokevirtual #4 // Method
java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 6: 0
line 7: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
MethodParameters:
Name Flags
args
}
2.3 图解方法执行流程
1原始 java 代码
package cn.itcast.jvm.t3.bytecode;
/**
* 演示 字节码指令 和 操作数栈、常量池的关系
*/
public class Demo3_1 {public static void main(String[] args) {int a 10;int b Short.MAX_VALUE 1;int c a b;System.out.println(c);}
}
2编译后的字节码文件
[rootlocalhost ~]# javap -v Demo3_1.class
Classfile /root/Demo3_1.class
Last modified Jul 7, 2019; size 665 bytes
MD5 checksum a2c29a22421e218d4924d31e6990cfc5
Compiled from Demo3_1.java
public class cn.itcast.jvm.t3.bytecode.Demo3_1
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 Methodref #7.#26 // java/lang/Object.init:()V
#2 Class #27 // java/lang/Short
#3 Integer 32768
#4 Fieldref #28.#29 //
java/lang/System.out:Ljava/io/PrintStream;
#5 Methodref #30.#31 // java/io/PrintStream.println:(I)V
#6 Class #32 // cn/itcast/jvm/t3/bytecode/Demo3_1
#7 Class #33 // java/lang/Object
#8 Utf8 init
#9 Utf8 ()V
#10 Utf8 Code
#11 Utf8 LineNumberTable
#12 Utf8 LocalVariableTable
#13 Utf8 this
#14 Utf8 Lcn/itcast/jvm/t3/bytecode/Demo3_1;
#15 Utf8 main
#16 Utf8 ([Ljava/lang/String;)V
#17 Utf8 args
#18 Utf8 [Ljava/lang/String;
#19 Utf8 a
#20 Utf8 I
#21 Utf8 b
#22 Utf8 c
#23 Utf8 MethodParameters
#24 Utf8 SourceFile
#25 Utf8 Demo3_1.java
#26 NameAndType #8:#9 // init:()V
#27 Utf8 java/lang/Short
#28 Class #34 // java/lang/System
#29 NameAndType #35:#36 // out:Ljava/io/PrintStream;
#30 Class #37 // java/io/PrintStream
#31 NameAndType #38:#39 // println:(I)V
#32 Utf8 cn/itcast/jvm/t3/bytecode/Demo3_1
#33 Utf8 java/lang/Object
#34 Utf8 java/lang/System
#35 Utf8 out
#36 Utf8 Ljava/io/PrintStream;
#37 Utf8 java/io/PrintStream
#38 Utf8 println
#39 Utf8 (I)V
{
public cn.itcast.jvm.t3.bytecode.Demo3_1();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack1, locals1, args_size1
0: aload_0
1: invokespecial #1 // Method java/lang/Object.
init:()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/itcast/jvm/t3/bytecode/Demo3_1;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack2, locals4, args_size1
0: bipush 10
2: istore_1
3: ldc #3 // int 32768
5: istore_2
6: iload_1
7: iload_2
8: iadd
9: istore_3
10: getstatic #4 // Field
java/lang/System.out:Ljava/io/PrintStream;
13: iload_3
14: invokevirtual #5 // Method
java/io/PrintStream.println:(I)V
17: return
LineNumberTable:
line 8: 0
line 9: 3
line 10: 6
line 11: 10
line 12: 17
LocalVariableTable:
Start Length Slot Name Signature
0 18 0 args [Ljava/lang/String;
3 15 1 a I
6 12 2 b I
10 8 3 c I
MethodParameters:
Name Flags
args
}
3常量池载入运行时常量池 4方法字节码载入方法区 5main 线程开始运行分配栈帧内存
stack2locals4 6执行引擎开始执行字节码
bipush 10
将一个 byte 压入操作数栈其长度会补齐 4 个字节类似的指令还有
sipush 将一个 short 压入操作数栈其长度会补齐 4 个字节
ldc 将一个 int 压入操作数栈
ldc2_w 将一个 long 压入操作数栈分两次压入因为 long 是 8 个字节
这里小的数字都是和字节码指令存在一起超过 short 范围的数字存入了常量池 istore_1
将操作数栈顶数据弹出存入局部变量表的 slot 1 ldc #3
从常量池加载 #3 数据到操作数栈
注意 Short.MAX_VALUE 是 32767所以 32768 Short.MAX_VALUE 1 实际是在编译期间计算
好的 istore_2 iload_1 iload_2 iadd istore_3 getstatic #4 iload_3 invokevirtual #5
找到常量池 #5 项
定位到方法区 java/io/PrintStream.println:(I)V 方法
生成新的栈帧分配 locals、stack等
传递参数执行新栈帧中的字节码 执行完毕弹出栈帧
清除 main 操作数栈内容 return
完成 main 方法调用弹出 main 栈帧
程序结束