「JVM」简述JIT

164 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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差不多