JVM - javap指令

2021/08/22 JVM 共 1356 字,约 4 分钟
Bob.Zhu

javap是jdk自带的反解析工具。它的作用就是根据class字节码文件,反解析出当前类对应的code区 (汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。

当然这些信息中,有些信息(如本地变量表、指令和代码行偏移量映射表、常量池中方法的参数名称等等) 需要在使用javac编译成class文件时,指定参数才能输出,比如,你直接javac xx.java,就不会在 生成对应的局部变量表等信息,如果你使用javac -g xx.java就可以生成所有相关信息了。如果你使用的 eclipse,则默认情况下,eclipse在编译时会帮你生成局部变量表、指令和代码行偏移量映射表等信息的。

通过反编译生成的汇编代码,我们可以深入的了解java代码的工作机制。比如我们可以查看i++;这行代码 实际运行时是先获取变量i的值,然后将这个值加1,最后再将加1后的值赋值给变量i。

通过局部变量表,我们可以查看局部变量的作用域范围、所在槽位等信息,甚至可以看到槽位复用等信息。

指令格式

前提条件,本文使用的java版本如下:

$ java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)

通过 javap -help 可以看到所有可以使用的参数:

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

一般常用的是 -v-l-c 三个选项。

  • javap -v classxx:不仅会输出行号、本地变量表信息、反编译汇编代码,还会输出当前类用到的常量池等信息。
  • javap -l classxx:会输出行号和本地变量表信息。
  • javap -c classxx:会对当前class字节码进行反编译生成汇编代码。

查看汇编代码时,需要知道里面的jvm指令,可以参考官方文档:The Java Virtual Machine Instruction Set

另外通过 jclasslib 工具也可以看到上面这些信息,而且是可视化的,效果更好一些。

开始写作吧

![image-alter](/image/post/2021/08/22/01/xxx.jpg)

参考资料

文档信息

Search

    Table of Contents