背景知识
profiling
profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。这里所收集的数据我们称之为程序的 profile。
即时编译just-in-time
是用来提升应用程序运行效率的技术。 通常而言,代码会先被 Java 虚拟机解释执行,之后反复执行的热点代码则会被即时编译成为机器码,直接运行在底层硬件之上。
HotSpot的即时编译器
HotSpot 虚拟机包含多个即时编译器 C1、C2 和 Graal。
Graal
Graal 是一个实验性质的即时编译器,可以通过参数 -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler 启用,并且替换 C2。
Introduction to Graal | Yudi Zheng (zhengyudi.github.io)
C1
对于执行时间较短的,或者对启动性能有要求的程序,我们采用编译效率较快的 C1,对应参数 -client。
C2
对于执行时间较长的,或者对峰值性能有要求的程序,我们采用生成代码执行效率较快的 C2,对应参数 -server。
C2 代码的执行效率要比 C1 代码的高出 30% 以上.
分层编译
Java 7 引入了分层编译(对应参数 -XX:+TieredCompilation)的概念,综合了 C1 的启动性能优势和 C2 的峰值性能优势。
分层编译将 Java 虚拟机的执行状态分为了五个层次。
1、解释执行;
2、执行不带 profiling 的 C1 代码【C1生成的机器码】;
3、执行仅带方法调用次数以及循环回边执行次数 profiling 的 C1 代码【C1生成的机器码】;
4、执行带所有 profiling 的 C1 代码【C1生成的机器码】;
5、执行 C2 代码【C2生成的机器码】。
1 层和 4 层为终止状态。当一个方法被终止状态编译过后,如果编译后的代码并没有失效,那么 Java 虚拟机是不会再次发出该方法的编译请求的。