这是我参与更文挑战的第 8 天,活动详情查看: 更文挑战
4.JIT编译器
编译器概念解释:
- Java语言的编译期其实是一点不确定的操作过程,可能是一个“前端编译器”(或叫编译器的前端)把Java代码转变为字节码文件
- 也可能是虚拟机的后端运行期编译器也即JIT编译器,把字节码转为机器码的过程
- 还可能指使用静态提前编译器直接把Java代码编译成本地机器码的过程。
什么时候使用JIT编译器?(热点探测)执行频率较高的代码称为热点代码
- **一个被多次调用的方法,或者一个方法内部多次循环的循环体都可以被称之为热点代码,**因此都可以通过JIT编译器编译为本地指令。由于这种编译方式发生在方法执行过程中,因此也被称为栈上替换(OSR)。
- 依靠一个热点探测功能来判断一个方法究竟是否为热点代码。
- 目前Hotspot虚拟机采用的是基于计数器的热点探测。分两种计数器
- 方法调用计数器:用于统计方法调用次数。默认阈值在Client模式下1500次,在Server模式下10000次,超过整个阈值就会触发JIT编译。平常使用的JVM默认就是Server模式。
- 回边计数器:统计循环体的循环次数。
热度衰减:
如果不做任何设置,方法调用统计器统计的并不是方法被调用的绝对次数,而是以恶搞相对的执行频率,即一段时间内方法被调用的次数。超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给JIT编译器编译器编译,那么这个方法调用计数器就会减少一半,这个过程称方法调用计数器热度的衰减,而这段时间就称为此方法的半衰周期。
5.Hotpot VM设置模式
默认情况Hotport VM采用的是解释器和JIT编译器并存的架构,也可以根据使用场景使用命令行设置完全使用解释器或者JIT编译器执行:
-Xint:完全采用解释器执行。-Xcomp:完全采用JIT编译器执行,如果编译时出现问题,解释器会介入。-Xmixed:采用混合模式执行。
JIT编译器的分类,Hotpot VM内置了两种JIT编译器,分别为Client Compiler和Server Compiler,简称C1和C2编译器,默认情况都是Server模式,可以使用命令显式指定模式:
-client:C1编译器会对字节码进行简单和可靠的优化,耗时短,有更快的编译速度。-server:C2编译器进行**耗时较长的优化,以及激进的优化。**但代码执行效率更高。64位操作系统固定这个编译器。
C2编译器的优化如下几种:
- 标量替换:用标量值代替聚合对象的属性值。
- 栈上分配:对于未逃逸的对象分配对象在栈上而不是堆上。
- 同步消除:清楚同步操作,通常是synchronized。