2. 字节码指令
2. 字節(jié)碼指令
2.1 入門
public cn.itcast.jvm.t5.HelloWorld();構(gòu)造方法的字節(jié)碼指令
? 2a b7 00 01 b1
另一個(gè)是public static void main(java.lang.String[]);主方法的字節(jié)碼指令
? b2 00 02 12 03 b6 00 04 b1
2.2javap工具
Oracle提供了javap工具來反編譯class文件
2.3圖解方法執(zhí)行流程
(1)原始Java代碼
package cn.itcast.jvm.t3.bytecode; /** *演示 字節(jié)碼指令 和 操作數(shù)棧、常量池的關(guān)系 */ 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)編譯后的字節(jié)碼文件
(3)常量池載入運(yùn)行時(shí)常量池
(4)方法字節(jié)碼載入方法區(qū)
(5)main線程開始運(yùn)行,分配棧幀內(nèi)存
(stack=2,locals=4)
(6)執(zhí)行引擎開始執(zhí)行字節(jié)碼
bipush 10
- 將一個(gè)byte壓入操作數(shù)棧(其長(zhǎng)度會(huì)補(bǔ)齊4個(gè)字節(jié)),類似的指令還有
- sipush將一個(gè)short壓入操作數(shù)棧(其長(zhǎng)度會(huì)補(bǔ)齊4個(gè)字節(jié))
- ldc將一個(gè)int壓入操作數(shù)棧
- ldc2_w將一個(gè)long壓入操作數(shù)棧(分兩次壓入,因?yàn)閘ong是8個(gè)字節(jié))
- 這里小的數(shù)字都是和字節(jié)碼指令存在一起,超過short范圍的數(shù)字存入了常量池
istore_1
- 將操作數(shù)棧頂數(shù)據(jù)彈出,存入局部變量表的slot 1
ldc #3
- 從常量池加載#3數(shù)據(jù)到操作數(shù)棧
- 注意Short.MAX_VALUE是32767,所有32768=Short.MAX_VALUE+1實(shí)際是在編譯期間計(jì)算好的
istore_2
iload_1
iload_2
iadd
istore_3
getstatic #4
iload_3
invokevirtual #5
- 找到常量池#5項(xiàng)
- 定位找到方法區(qū)Java/io/PrintStream.println:(I)V方法
- 生成新的棧幀(分配locals、stack等)
- 傳遞參數(shù),執(zhí)行新棧幀中的字節(jié)碼
- 執(zhí)行完畢,彈出棧幀
- 清除main操作數(shù)棧內(nèi)容
return
- 完成main方法調(diào)用,彈出main棧幀
- 程序結(jié)束
總結(jié)
- 上一篇: bootstrap table 列拖动变
- 下一篇: 前端_网页编程 Form表单与模板引擎(