深入拆解 Java 虚拟机
郑雨迪
Oracle 高级研究员,计算机博士
87446 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 40 讲
模块四:黑科技 (3讲)
深入拆解 Java 虚拟机
15
15
1.0x
00:00/00:00
登录|注册

【工具篇】 常用工具介绍

查阅Java虚拟机中对象的内存分布
反汇编和汇编操作
修改class文件的字节码
ASMifier
应用领域
字节码分析及修改框架
JOL
ASMTools
选项 -p 和 -v
查阅Java字节码
ASM
OpenJDK项目Code Tools
javap
JVM常用工具介绍

该思维导图由 AI 生成,仅供参考

在前面的文章中,我曾使用了不少工具来辅助讲解,也收到了不少同学留言,说不了解这些工具,不知道都有什么用,应该怎么用。那么今天我便统一做一次具体的介绍。本篇代码较多,你可以点击文稿查看。

javap:查阅 Java 字节码

javap 是一个能够将 class 文件反汇编成人类可读格式的工具。在本专栏中,我们经常借助这个工具来查阅 Java 字节码。
举个例子,在讲解异常处理那一篇中,我曾经展示过这么一段代码。
public class Foo {
private int tryBlock;
private int catchBlock;
private int finallyBlock;
private int methodExit;
public void test() {
try {
tryBlock = 0;
} catch (Exception e) {
catchBlock = 1;
} finally {
finallyBlock = 2;
}
methodExit = 3;
}
}
编译过后,我们便可以使用 javap 来查阅 Foo.test 方法的字节码。
$ javac Foo.java$ javap -p -v FooClassfile ../Foo.class Last modified ..; size 541 bytes MD5 checksum 3828cdfbba56fea1da6c8d94fd13b20d Compiled from "Foo.java"public class Foo minor version: 0 major version: 54 flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #7 // Foo super_class: #8 // java/lang/Object interfaces: 0, fields: 4, methods: 2, attributes: 1Constant pool: #1 = Methodref #8.#23 // java/lang/Object."<init>":()V #2 = Fieldref #7.#24 // Foo.tryBlock:I #3 = Fieldref #7.#25 // Foo.finallyBlock:I #4 = Class #26 // java/lang/Exception #5 = Fieldref #7.#27 // Foo.catchBlock:I #6 = Fieldref #7.#28 // Foo.methodExit:I #7 = Class #29 // Foo #8 = Class #30 // java/lang/Object #9 = Utf8 tryBlock #10 = Utf8 I #11 = Utf8 catchBlock #12 = Utf8 finallyBlock #13 = Utf8 methodExit #14 = Utf8 <init> #15 = Utf8 ()V #16 = Utf8 Code #17 = Utf8 LineNumberTable #18 = Utf8 test #19 = Utf8 StackMapTable #20 = Class #31 // java/lang/Throwable #21 = Utf8 SourceFile #22 = Utf8 Foo.java #23 = NameAndType #14:#15 // "<init>":()V #24 = NameAndType #9:#10 // tryBlock:I #25 = NameAndType #12:#10 // finallyBlock:I #26 = Utf8 java/lang/Exception #27 = NameAndType #11:#10 // catchBlock:I #28 = NameAndType #13:#10 // methodExit:I #29 = Utf8 Foo #30 = Utf8 java/lang/Object #31 = Utf8 java/lang/Throwable{ private int tryBlock; descriptor: I flags: (0x0002) ACC_PRIVATE private int catchBlock; descriptor: I flags: (0x0002) ACC_PRIVATE private int finallyBlock; descriptor: I flags: (0x0002) ACC_PRIVATE private int methodExit; descriptor: I flags: (0x0002) ACC_PRIVATE public Foo(); descriptor: ()V flags: (0x0001) 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 1: 0 public void test(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: stack=2, locals=3, args_size=1 0: aload_0 1: iconst_0 2: putfield #2 // Field tryBlock:I 5: aload_0 6: iconst_2 7: putfield #3 // Field finallyBlock:I 10: goto 35 13: astore_1 14: aload_0 15: iconst_1 16: putfield #5 // Field catchBlock:I 19: aload_0 20: iconst_2 21: putfield #3 // Field finallyBlock:I 24: goto 35 27: astore_2 28: aload_0 29: iconst_2 30: putfield #3 // Field finallyBlock:I 33: aload_2 34: athrow 35: aload_0 36: iconst_3 37: putfield #6 // Field methodExit:I 40: return Exception table: from to target type 0 5 13 Class java/lang
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了JVM常用工具javap的使用方法和输出结果,以及OpenJDK项目Code Tools中的ASMTools和JOL工具,以及ASM字节码框架。ASMTools提供了反汇编和汇编操作,可用于简单的字节码修改,而JOL工具则可查阅Java虚拟机中对象的内存分布。ASM字节码框架被广泛应用于许多项目中,包括生成新的class文件和修改已有的class文件。文章通过丰富的代码示例和详细的解释,帮助读者快速了解了这些工具的功能和使用方法。对于想要深入了解JVM工具的读者来说,这篇文章是一份有价值的参考资料。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Java 虚拟机》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(30)

  • 最新
  • 精选
  • hey,吕布
    老师,文中代码格式异常了,早上打开还好的

    作者回复: 这么诡异,我反馈一下

    2018-08-03
    2
  • xianhai
    能不能介绍一下metaspace的tracing 工具?怎样看metaspace里的内存分布?

    作者回复: 在第三部分我会介绍一些常用的分析工具。看Metaspace的话可以试试通过jmap -clstats 来查看各个类的情况。我个人用的比较多的是flight recorder,不过我记得只能查看总的Metaspace使用量。

    2018-08-03
    2
  • sgl
    为什么方法里用的指令只有入栈,没有出栈?难道putfield这类指令,用了操作数栈上的数据以后,会自己调用出栈指令?

    作者回复: putfield 可以想成 出栈再消耗数据

    2018-10-20
    1
  • 倔强
    为什么我允许F oo Dump报无法加载主类?是因为没有main方法?

    作者回复: 多谢指出!应该是Wrapper,而且cp也需要添加当前目录,即-cp /path/to/ASM.jar:. Wrapper

    2018-08-03
    1
  • 志远
    1.如何汇编至class文件啊?用什么工具? 2.字节码的局部变量和java程序中的局部变量有什么区别?

    作者回复: 1. 你可以通过ASMTools反汇编class文件,再将输出的文本汇编回class文件 2. 字节码中的局部变量会更多一些,Java编译器会根据需要存储一些非Java程序中的局部变量

    2018-08-03
    1
  • xianhai
    reflection inflation 会不会造成java 8 metaspace: Outofmemory

    作者回复: Reflection inflation会生成新的类,理论上是会导致你说的这个错误的。

    2018-08-03
    1
  • Ivan
    可以在运行时通过class的实例,获取到这个类的源代码或者汇编代码么?或者说怎么查看动态代理生成的类的源代码?

    作者回复: 一个是在加载时用javaagent或者JVMTI截获,另外一个是用一些调试器。关于后者,你可以试试JDK中的HotSpot Debugger(HSDB),在lib/sa-jdi.jar里。

    2018-08-03
    1
  • 刹那间的永恒
    果然还是一点都看不懂,老师,什么阶段适合接触虚拟机?
    2018-08-04
    6
    59
  • xiaobang
    能系统的介绍下Java字节码吗,每次看到都是靠猜
    2018-08-20
    2
    9
  • Thomas
    老师后面讲下反射跟动态代理~很期待专门写一篇JAVA特性的原理。
    2018-08-03
    8
收起评论
显示
设置
留言
30
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部