HSDIS java汇编工具分析 JVM 代码执行
HSDIS,一个Sun官方推荐的HotSpot虚拟机JIT编译代码的反汇编插件。
windows 电脑上, 在 hsdis HotSpot Disassembly Plugin Downloads (chriswhocodes.com) 下载 hsdis-amd64.dll 安装到 %JAVA_HOME\jre\bin\server 目录下
验证是否安装成功
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version
通过 JITwatch 的 release 知道,如果未检测到 hsdis,则 JITWatch 沙盒将提供从 https://chriswhocodes.com/hsdis/ 下载hsdis-amd64.dll
测试代码
package com.person;
public class VolatileVisibilityTest {
private static volatile boolean initFlag = false;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
System.out.println("waiting data.....");
while (!initFlag){
}
System.out.println("=========success.");
}).start();
Thread.sleep(2000);
new Thread(()->prepareData()).start();
}
public static void prepareData(){
System.out.println("prepare data end.");
initFlag = true;
}
}
没配置VM optons参数,控制台输出程序结果
waiting data.....
prepare data end.
=========success.
配置VM optons
参数, IDEA 找到Edit Configurations
,点击 Modify options
找到 Add VM options
或者使用快捷键Alt + F
VM optons 详细参数可以查看.java 工具参考_vm参数 和 java (oracle.com)
-server
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintAssembly
-XX:+LogCompilation
-XX:LogFile=D:\Java\IdeaProjects\test\data\log\%t-hotspot.log
只需要编译 *VolatileTest.increase
和 *VolatileTest.decrease
这两个方法,并且将日志输出到 /var/log/hotspot.log
文件中,VM options
参数是这样子的
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintAssembly
-Xcomp
-XX:CompileCommand=compileonly,*VolatileTest.increase
-XX:CompileCommand=compileonly,*VolatileTest.decrease
-XX:+LogCompilation
-XX:LogFile=/var/log/hotspot.log
注意:data\log 目录必须先配置好
配置VM optons参数,控制台输出程序结果,可以看到汇编语言
4bae3f9a8: mov rsi,rdx
0x00000154bae3f9ab: mov rdi,154d39aab18h ; {metadata(method data for {method} {0x00000154d3888920} 'next' '()Ljava/lang/Object;' in 'java/util/Collections$UnmodifiableCollection$1')}
0x00000154bae3f9b5: mov esi,dword ptr [rsi+8h]
0x00000154bae3f9b8: shl rsi,3h
0x00000154bae3f9bc: cmp rsi,qword ptr [rdi+110h]
0x00000154bae3f9c3: jne 154bae3f9d2h
0x00000154bae3f9c5: add qword ptr [rdi+118h],1h
0x00000154bae3f9cd: jmp 154bae3fa38h
0x00000154bae3f9d2: cmp rsi,qword ptr [rdi+120h]
0x00000154bae3f9d9: jne 154bae3f9e8h
0x00000154bae3f9db: add qword ptr [rdi+128h],1h
0x00000154bae3f9e3: jmp 154bae3fa38h
0x00000154bae3f9e8: cmp qword ptr [rdi+110h],0h
0x00000154bae3f9f3: jne 154bae3fa0ch
0x00000154bae3f9f5: mov qword ptr [rdi+110h],rsi
......省略大量代码
[Exception Handler]
[Stub Code]
0x00000154bae73720: call 154bad548e0h ; {no_reloc}
0x00000154bae73725: mov qword ptr [rsp+0ffffffffffffffd8h],rsp
0x00000154bae7372a: sub rsp,80h
0x00000154bae73731: mov qword ptr [rsp+78h],rax
0x00000154bae73736: mov qword ptr [rsp+70h],rcx
0x00000154bae7373b: mov qword ptr [rsp+68h],rdx
0x00000154bae73740: mov qword ptr [rsp+60h],rbx
0x00000154bae73745: mov qword ptr [rsp+50h],rbp
0x00000154bae7374a: mov qword ptr [rsp+48h],rsi
0x00000154bae7374f: mov qword ptr [rsp+40h],rdi
0x00000154bae73754: mov qword ptr [rsp+38h],r8
0x00000154bae73759: mov qword ptr [rsp+30h],r9
0x00000154bae7375e: mov qword ptr [rsp+28h],r10
0x00000154bae73763: mov qword ptr [rsp+20h],r11
0x00000154bae73768: mov qword ptr [rsp+18h],r12
0x00000154bae7376d: mov qword ptr [rsp+10h],r13
0x00000154bae73772: mov qword ptr [rsp+8h],r14
0x00000154bae73777: mov qword ptr [rsp],r15
0x00000154bae7377b: mov rcx,7794f910h ; {external_word}
0x00000154bae73785: mov rdx,154bae73725h ; {internal_word}
0x00000154bae7378f: mov r8,rsp
0x00000154bae73792: and rsp,0fffffffffffffff0h
0x00000154bae73796: mov r10,7762e3e0h ; {runtime_call}
0x00000154bae737a0: call indirect r10
0x00000154bae737a3: hlt
[Deopt Handler Code]
0x00000154bae737a4: mov r10,154bae737a4h ; {section_word}
0x00000154bae737ae: push r10
0x00000154bae737b0: jmp 154bad27600h ; {runtime_call}
0x00000154bae737b5: hlt
0x00000154bae737b6: hlt
通过命令行查看 java 汇编
javac Test.java
-server -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation
-XX:LogFile=D:\Java\IdeaProjects\test\data\log\%t-hotspot.log
JITWatch(Just In Time compilers)
JITWatch的 GitHub 的地址https://github.com/AdoptOpenJDK/jitwatch
JITWatch 是 HotSpot JIT 编译器的日志分析器和可视化程序
JITWatch wiki地址
描述:
用于了解 Java 热点实时 (JIT) 编译器在程序执行期间的行为的工具。
通过处理热点.log JVM 输出文件来工作。
该工具最初是作为一种学习工具,以更好地了解热点和JavaFX。
我希望你觉得它有用:)
为什么我要使用 JIT 监视?
- 验证您认为对性能至关重要的方法是否在程序执行期间进行了 JIT 编译。
- 要了解在执行中的哪个阶段编译了性能关键型方法。
- 了解调整 JVM 编译阈值的效果。
- 为了更好地了解热点 JIT 编译器。
- 查看源代码如何转换为字节码和程序集。
特征
- 浏览类树并查看哪些方法已进行 JIT 编译、JIT 编译发生的时间以及有关编译的信息。
- 装载源代码、jar 和类树以跳转到方法的源代码、字节码和程序集。
- 绘制随时间变化的 JIT 编译,并可视化方法的 JIT 编译时间。
- 查看最大本机方法、字节码最多的方法、最长编译时间等的顶级列表。
- 在简化的BSD许可证下开源。
通过命令,启动JITWatch程序
java -jar jitwatch-ui-1.4.7-shaded-win.jar
在 jitwatch 中配置 idea 中的测试程序
-
页面选择 config ,配置要调试的项目 src 源码路径,和 class 编译路径
-
打开 hotspot.log
-
点击 start ,选中指定的类,再选择右侧的具体方法,则弹出jit编译结果
展示java 源码 字节码 汇编语言
参考资料:
(330条消息) openjdk12 hsdis windows构建_窗外蓝天的博客-CSDN博客_hsdis-amd
java汇编指令查看工具jitwatch - 掘金 (juejin.cn)
Building hsdis for OpenJDK 15 - Gunnar Morling
Developers disassemble! Use Java and hsdis to see it all. (oracle.com)
(330条消息) Java反汇编工具hsdis-jitwatch使用_At小明同学的博客-CSDN博客_java 反汇编工具
(330条消息) windows环境下使用jitwatch查看字节码以及汇编指令_d303577562的博客-CSDN博客
JIT的Profile神器JITWatch - 知乎 (zhihu.com)
How to build hsdis-amd64.dll and hsdis-i386.dll on Windows (dropzone.nfshost.com)