java反编译JVM指令入门
一、概述
javac 是java语言编程编译器。 全称java compiler。 javac工具读由java语言编写的类和接口的定义,并将它们编译成字节代码的class文件。 javac 可以隐式编译一些没有在命令行中提及的源文件。
javap是jdk自带的反解析工具。它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。
针对javac和javap相关命令,在已配置好JDK环境变量的终端,使用javac -help
和javap -help
即可查找
1 | 用法: javac <options> <source files> |
1 | 用法: javap <options> <classes> |
二、入门实战
1、创建java源程序
新建Hello.java
文件
1 | public class Hello { |
2、反编译JVM指令分析
在当前目录下打开Cmd,输入javac Hello.java
后,成功将源文件编译成Hello.class文件,之后进行反编译,输入命令javap -c Hello.class > Hello.txt
将指令结果输出到txt文件
1 | Compiled from "Hello.java" |
三、总结与提高
1、总结
1、通过javap命令可以查看一个java类反汇编、常量池、变量表、指令代码行号表等等信息。
2、平常,我们比较关注的是java类中每个方法的反汇编中的指令操作过程,这些指令都是顺序执行的,
3、一个方法的执行通常会涉及下面几块内存的操作:
-
java栈中:局部变量表、操作数栈。这些操作基本上都值操作。
-
java堆。通过对象的地址引用去操作。
-
常量池。
-
其他如帧数据区、方法区等部分
在做值相关操作时:
一个指令,可以从局部变量表、常量池、堆中对象、方法调用、系统调用中等取得数据,这些数据(可能是指,可能是对象的引用)被压入操作数栈。
一个指令,也可以从操作数数栈中取出一到多个值(pop多次),完成赋值、加减乘除、方法传参、系统调用等等操作。
2、提高
官网JVM指令集:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5
下面是较为常见的指令集,具体还可以参考《深入理解Java虚拟机第二版》、《Java虚拟机规范 JavaSE8版》两本书
1 | 指令码 助记符 说明 |
参考文章: