JITWatch查看字节码被JIT编译后的汇编代码

原创 吴就业 155 0 2020-01-05

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/6a3890352f534963b15a9c06858990cc

作者:吴就业
链接:https://wujiuye.com/article/6a3890352f534963b15a9c06858990cc
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

本篇文章写于2020年01月05日,从公众号同步过来(博客搬家),本篇为原创文章。

最近看书看到关于volitale关键字与jmm内存模型的介绍,这个知识点似乎看了好多次,背都能背下来了。但理论性的东西真的很容易忘记,看不到摸不着。于是乎,我上网搜索看底层机器指令的实现,发现不少文章说可以看到java编译后的汇编代码,于是了解到jitwatch这个工具,从名字上也能看出jit编译器监视的意思。

今天是想跟大家分享如何查看java经过jit编译后生成的汇编代码。

Java文件编译后生成class文件,包含字节码,字节码由jvm解释执行,为了提高程序的运行效率,java提供了jit编译器,编译热代码。如果一段代码经常被调用,会被jit编译为机器码,后续调用不再解释执行。所以要查看汇编代码必须要让这段代码被多次调用。

使用HSDIS查看汇编代码

HSDISHotSpot disassembler的缩写,要使用HSDIS需要下载hsdis-amd64.dylib

未下载hsdis-amd64.dylib使用hsdis

适用于mac系统hsdis-amd64.dylib下载链接:

https://github.com/evolvedmicrobe/benchmarks/blob/master/hsdis-amd64.dylib?spm=a2c4e.10696291.0.0.13ce19a46a5XRa&file=hsdis-amd64.dylib

将其放到$JAVA_HOME/jre/lib/目录下

hsdis-amd64.dylib安装位置

可通过命令行使用javac命令编译运行java文件,在命令行执行java -XX:+PrintAssembly -XX:+UnlockDiagnosticVMOptions xxx >> assembly_code.txt就能得到大量汇编代码。也可以在idea中通过配置VM参数使用,如下图。

idea配置vm参数

debug后会在idea的控制台输出汇编代码

hsdis输出汇编代码

但是这种方式并不友好,会将java包下的代码也输出,很难找到某个类的某个方法的汇编代码,如果只是一个简单的java类还好。

使用VisualVM的插件

这种方法我没有试过,不过确实有这么个插件SAPlugin

VisualVM SAPlugin

使用JITWatch

jitwatch是一个开源项目,有详细的使用文档。需要下载代码自己编译。提前条件都是需要hsdis-amd64.dylib的支持。

下载链接:

https://github.com/AdoptOpenJDK/jitwatch/releases

不要下载master分支下的代码,下载releases版本的代码。直接下载master分支下的代码会出现编译问题,所以我选择下载releases版本。编译运行可看wiki。我习惯使用gradlegradle使用gradlew clean build run编译运行。

jitwatch sandbox

jitwatch sandbox配置

jitwatch java代码-字节码-汇编代码的映射

图中的红框就是显示源代码与字节码与汇编代码的映射,可以通过方向键的上下键移动红框。除代码映射之外,还可以选择查看某个方法。此外,还可以返回主窗口,查看哪些类被JIT编译了,以及可以选择一个感兴趣的类打开TriView查看汇编代码。

jitwatch选择方法查看汇编代码

#后端

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

Dubbo路由功能实现灰度发布及源码分析

灰度发布是实现新旧版本平滑过渡的一种发布方式,即让一部分服务更新到新版本,如果这部分服务没有什么问题,再将其它旧版本的服务更新。而实现简单的灰度发布我们可以使用版本号控制,每次发布都更新版本号,新更新的服务就不会调用旧的服务提供者。

JVM垃圾回收GC Root与安全点Safepoint

我看很多资料在介绍`GC Root`时,并没有说栈帧的操作数栈上引用的对象也是`GC Root`,包括我去翻阅《深入理解Java虚拟机》这本书也是一样。所以我才好奇。

服务提供者假死,记一次full gc问题排查

线上某服务一直运行很稳定,最近突然就`cpu`百分百,`rpc`远程调用全部失败,并走了`mock`逻辑。重启后,一个小时后问题又重现。于是`dump`线程栈信息,但不仔细看也看不出什么问题。于是就有了一番排查历程。

Spring Cloud Kubernetes入门必知运维知识之Docker

容器化部署就是一次配置到处使用,例如将安装nginx配置nginx这一系列工作制作成一个镜像,在服务器上通过docker拉取镜像并启动容器即可完成nginx的部署。

Dubbo源码,详解dubbo协议数据包及解包过程

Dubbo框架的传输层默认使用dubbo协议,这也是一种RPC远程通信协议。学习Dubbo,我们有必要了解dubbo协议长什么样,最好的办法就是从源码中寻找答案。

Netty源码-详解Http协议的数据包解码过程

今天我们来分析下`netty`是如何解析`http`协议数据包的。重点是分析`HttpObjectDecoder`类的`decode`方法的源码,`http`协议数据包的解码操作都是在该方法中完成的。