使用 HSDIS 和 JITWatch 探索 Java 汇编指令
Java 虚拟机(JVM)作为一种现代化的虚拟机,具备即时编译(Just-In-Time, JIT)功能,可以将热点代码编译为高效的本地机器码以提高性能。在实际开发和性能调优中,我们可能需要分析 JVM 将 Java 字节码编译成的汇编指令。本篇博客将详细介绍如何使用 HSDIS 和 JitWatch 工具来查看和分析这些生成的汇编代码。
一、HSDIS 简介
HSDIS(HotSpot Disassembler)是 HotSpot JVM 的反汇编插件,可以将 JIT 编译器生成的机器码转换成人类可读的汇编指令。HSDIS 是 JDK 的非官方组件,因此需要手动下载或编译。
二、JITWatch 简介
JITWatch 是一个用于分析 JVM JIT 编译过程的可视化工具。它可以解析 JVM 日志文件(通常是通过 -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation
生成的),并展示 JIT 编译的详细信息,包括内联决策和汇编代码。
三、环境准备
以下步骤基于 Linux 环境,但可以适配其他操作系统。
安装 JDK
确保你的系统安装了支持 HSDIS 和 JIT 日志的 JDK(推荐使用 OpenJDK 或 Oracle JDK 8/11,
本文使用的是Oracle JDK 8
)。下载或编译 HSDIS
检查你的 JDK 是使用哪种架构(
x86_64
或aarch64
)。安装 HSDIS:
方式一: 从https://github.com/liuzhengyang/hsdis下载编译
本文使用该方式
。方式二:
从 GraalVM 的 GitHub 仓库:https://github.com/graalvm/labs-openjdk-11 下载预编译的 HSDIS 动态库,或者自己编译:1
2
3git clone https://github.com/openjdk/jdk.git
cd jdk/src/utils/hsdis
make ARCH=<x86_64 或 aarch64>方式三: 从https://chriswhocodes.com/hsdis/下载已经编译好的
- 将生成的
hsdis-<arch>.so
放到 JDK 的$JAVA_HOME/jre/bin/server
目录下。
- 安装 JITWatch
- 从 JitWatch GitHub 仓库:https://github.com/AdoptOpenJDK/jitwatch 下载最新版本。
- 解压后运行
launchUI.sh
(Linux/macOS)或launchUI.bat
(Windows)。 - 确保你已安装 Java 8 或更高版本。
生成汇编代码
1. 编写测试代码
首先,创建一个简单的 Java 类用于测试:
1 | public class Test { |
2. 使用 HSDIS 查看汇编
运行上述代码时,启动 JVM 时添加 HSDIS 配置参数:
1 | -XX:+UnlockDiagnosticVMOptions |
其中:
-XX:+PrintAssembly
:启用汇编代码打印。-XX:+LogCompilation
:生成 JIT 日志文件。-XX:LogFile
:指定 JIT 日志文件的位置。
运行后,终端将输出大量信息,其中包含 compute
方法的汇编代码。你可以通过分析这些汇编指令了解 JVM 如何优化你的代码。
3. 使用 JitWatch 分析
- 配置源码目录和编译字节码目录
2.打开生成的 hotspot.log 文件。并启动分析
常见问题
未加载 HSDIS 动态库
- 检查 HSDIS 文件名是否正确,并确认其路径与 JVM 的
lib
目录匹配。 - 使用
java -version
确认使用的是预期的 JVM。
- 检查 HSDIS 文件名是否正确,并确认其路径与 JVM 的
汇编输出乱码
- 确保 JVM 使用的指令集架构与 HSDIS 编译版本一致(如 x86_64)。
- 检查终端编码是否支持正确显示特殊字符。
JitWatch 无法加载日志
- 确保日志文件完整无误。
- 使用
grep
检查日志是否包含方法编译记录。
总结
通过 HSDIS 和 JitWatch,我们可以深入了解 JVM 的 JIT 编译过程以及生成的汇编代码。对于性能调优或研究 JVM 工作原理,这些工具提供了强大的支持。希望本文能够帮助你快速上手这些工具,进一步探索 Java 性能优化的奥秘!