一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情。
概述
作用:将字节码指令解释/编译为对应平台上的本地机器指令(将字节码翻译成机器语言)。并按照程序计数器来操作堆栈中的数据,并在虚拟机栈中进行对应的操作计算等
JIT编译器
Hotspot执行代码有两种方式(协作执行)
- 针对常用的代码,使用JIT技术编译成机器码直接执行。
- 将源代码编译成字节码,在运行的时候通过解释器将字节码转换成机器码执行
JIT(just in time)即使编译技术。
只使用JIT的问题:程序启动需要耗时很长时间才能使用(启动需要编译所有代码 )
整合两者:虚拟机刚启动时,解释器先发挥作用,不用等待即使编译器全部编译完成,可以省去需要不必要的编译时间。随着程序时间的推移,即使编译器逐步发挥作用,根据热点探测功能,将有价值的字节码编译成机器码,来换取更高的程序执行效率
JIT什么时候使用(热点探测)
- 前端编译器:即在使用代码前就将代码编译好。比如将.java编译成.class的过程
- 后端运行期编译器:就是JIT,在代码执行期间即时的将字节码转变成机器码的过程
- 静态提前编译器:就是将.java直接编译成机器码。运行期间就没有编译的操作了(AOT编译器)
什么时候使用JIT
根据代码的执行频率。(一个多次调用的方法,或者方法体中循环较多次的方法体)执行较多的就是热点代码。
热点探测功能:基于计数器的热点探测
- 方法调用计数器来统计方法的调用次数。
- 回变计数器来统计循环体的执行循环次数
热点衰减:在一定时间限度内,如果方法调用次数仍然不足提交进行编译器编译。就将调用次数减少一半。(这个一定时间限度使用就是-XX:-UseCounterDecay)
使用JIT
正常hotspot的默认模式是混合模式。也就是既有解释器也有JIT。
可以通过java -Xint -version
,将修改成解释器模式之下
java -Xcomp -version
修改成纯即时编译器的模式并打出信息。也就是第一次就进行编译进行之下
JIT的分类(C1编译器和C2编译器)
-
C1编译器:Client Compiler 表示Java虚拟机运行在client模式下(桌面客户端等)
会对字节码进行简单和可靠的优化,耗时短(开机时间短,但是开机后的运行速度稍微差点意思)
-
C2编译器:Server Compiler 表示Java虚拟机运行在server上(网页的CS模式下的后台应用程序)
会进行耗时较长的优化以及激进优化,耗时长(开机时间长,但是开机后的运行速度稍微好一点)
Graal编译器,JDK10之后的编译器,需要显式的去开启。效率和C2差不多