共计 2664 个字符,预计需要花费 7 分钟才能阅读完成。
简介
老是使用命令行工具在现代化社会好像已经跟不上节奏了,尤其是在做 JIT 分析时,使用 LogCompilation 输出的日志实在是太大了,让人望而生畏。有没有什么更加简便的方法来分析 JIT 日志呢?快来和小师妹一起来学习 JITWatch 吧。
什么是 JIT
小师妹,F 师兄,JIT 就是 Just In Time compilers。能不能再总结一下 JIT 到底是做什么的呢?
当然没问题,JIT 主要有两个作用,第一个作用大家应该已经知道了,就是在运行时将 byte code 编译成为机器码,提高程序的执行速度。
第二个作用就是在运行时对代码进行优化,同样的也对性能进行提升。
JIT 中有两种编译器,C1 代表的是 Client Compiler,C2 代表的是 Server Compiler。
其中 C1 只是简单的编译,而 C2 在收集到更多信息之后,会进行更加深入的编译和优化。
常见的优化手段有:Loop unrolling, Inlining, Dead Code Elimination,Escape analysis, Intrinsics, Branch prediction 等。
JDK8 中会默认启动分层编译。你也可以使用 -XX:+TieredCompilation 来手动启动它。
更多精彩内容且看:
- 区块链从入门到放弃系列教程 - 涵盖密码学, 超级账本, 以太坊,Libra, 比特币等持续更新
- Spring Boot 2.X 系列教程: 七天从无到有掌握 Spring Boot- 持续更新
- Spring 5.X 系列教程: 满足你对 Spring5 的一切想象 - 持续更新
- java 程序员从小工到专家成神之路(2020 版)- 持续更新中, 附详细文章教程
JITWatch 简介
小师妹:F 师兄,上次你讲的 LogCompilation 和 PrintCompilation 输出结果还是太复杂了,尤其是 LogCompilation,输出的结果有十几 M,分析起来好难。有没有更简单一点的办法,让我的工作效率加倍呢?
这个必须有,有需求就有市场,有需求就有大神出场。今天给你介绍一个工具叫做 JITWatch。
JITWatch 是一个大神做的 JIT 日志的可视化分析工具。在使用它之前你可能觉得它有点强大,在使用后你就会觉得它真的是强大。
运行 JITWatch
小师妹:F 师兄,这么强大的工具,快快介绍我使用吧。
完全没有问题,不过 JITWatch 没有现成的打包好的可执行文件。没错,你需要到 github 上面下载源码。
下载完毕,可以执行:
mvn clean compile test exec:java
就可以开启 JITWatch 之旅了。
JITWatch 详解
小师妹:F 师兄,这么好用的工具为什么不打个包出来让大家直接用呢?还要下载源码这么麻烦。
其实吧,JITWatch 为了大家方便使用,自带一个 Sandbox 功能,提供了一些可以直接在 JITWatch 中运行的代码,同时 JITWatch 可以实现源码的实时比对功能。所以需要大家下载源码。
闲话休提,我们开启 JITWatch 之旅吧。
入眼就是如此朴实无华的界面,让人感觉总有点 … 重剑无锋, 大巧不工。高手做的 UI 就是这么的完美。
接下来我们需要运行一个程序,来实时感受一下 JITWatch 的魅力。
看到左边最上角的 sandbox 了吗?点开它可以看到下面的 sandbox 页面:
这一个页面会选择一个 sadbox 中的例子展示给你,大家注意下面的输出框的说明,它会显示你的 Disassembler 是否可用。如果想要安装 disassembler,请参照我之前的文章。
如果你对这个例子不满意,或者你想使用自己的代码,那也完全没有问题。点击 config。
这里你可以配置源代码的路径,可以选择 VM 的语言,还有各种 VM 的选项,下面的选项相信我在之前的文章中都已经介绍过了吧。
如果还有不懂的小伙伴,微信我,私聊我,1 对 1 现场教学。
万事俱备,只欠东风,开始吧,我可是要成为 Java 王的男人!
然后我们就进入了 TirView 界面,这里我们可看到主界面分成了三部分,源代码,ByteCode 和 Assembly。
小师妹:真是热泪盈眶啊,终于不需要自己去添加那些 XX 参数了。面向界面编程,真好。
上面还有几个按钮,这里简单介绍一下他们的功能,具体的界面这里就不截图了,因为实在是太多了 ….
Chain 会展示调用链。
Journal 就是之前使用 LogCompilation 产生的 xml 日志。
LNT, 全称是 line number table。— 目前我还不知道这个是做什么用的,有知道的朋友,请给我留言。
然后就是 Inlined into 功能了,这个功能要详细讲一下,因为会影响到程序的执行效率。
还记得之前举的 inline 的例子吗?
int a = 1;
int b = 2;
int result = add(a, b);
...
public int add(int x, int y) {return x + y;}
int result = a + b; // 内联替换
上面的 add 方法可以简单的被替换成为内联表达式。
JITWatch 可以显示方法是否被 inlined,并且显示出 inlined 的原因。
点击 BCI 可以显示关联的 inlined 的代码。大家自行体会。
现在再让我们回到可爱又有风格的主页面:
左边是源代码,包含了 JDK 自己的代码,如果你想详细的分析 JDK 自己代码的优化,那么这是一个非常好的工具。
右边显示的是被 JIT 编译的类和方法,并且展示了编译级别和编译的时间。
右上角又有一排按钮,Config 是用来配置运行的代码。
TimeLine 是以图形的形式展示 JIT 编译的时间轴。
Histo 是直方图展示的一些编译信息。
TopList 里面是编译中产生的一些对象的或者数据的排序。
Cache 是 free code cache 空间。
NMethod 是 native 方法。
Threads 是 JIT 编译的线程。
TriView 就是我们最开始展示的面板。
最后我们重点讲一下 Suggestion:
Suggestion 是对代码的一些优化建议。
从上图我们可以看到在调用 String 的 hashMap 方法时候无法 inlined, 因为被调用的方法太大了,超出了最大 inlining size。
总结
所以,我们通过 JITWatch 可以学到什么呢?最最重要的是我们可以通过 JITWatch 来分析 JIT 的运行原理和本质。然后 inlined 的方法不要太大了,否则影响执行效率。
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/jvm-jit-jitwatch/
本文来源:flydean 的博客
欢迎关注我的公众号: 程序那些事,更多精彩等着您!