参考基本功 | Java即时编译器原理解析及实践 、 Java 面试-即时编译( JIT )
作用
当虚拟机发现某个方法或代码块的运行特别频繁的时候,就会把这些代码认定为热点代码。
Client端的是1500 Service端的是10000。
概念
在字节码转换为机器码的过程中,虚拟机中还存在着一道编译,那就是即时编译
编辑器分类
C1 编译器
C1 编译器是一个简单快速的编译器,主要的关注点在于局部性的优化,适用于执行时间较短或对启动性能有要求的程序,也称为Client Compiler,例如,GUI 应用对界面启动速度就有一定要求。
C2 编译器
C2 编译器是为长期运行的服务器端应用程序做性能调优的编译器,适用于执行时间较长或对峰值性能有要求的程序,也称为Server Compiler,例如,服务器上长期运行的 Java 应用对稳定运行就有一定的要求。
Graal Compiler(JDK9开始的)同C2一样也是service端的。
即时编译触发时机
当方法的调用次数和循环回边的次数的和,超过由参数-XX:CompileThreshold指定的阈值时(使用C1时,默认值为1500;使用C2时,默认值为10000),就会触发即时编译。
编译优化(优化方式)
- 中间表达形式(Intermediate Representation): 能发现死的变量,无用代码
- 方法内联 :分为,方法内联和虚函数内联。
虚函数内联。java所有的为private的都是虚函数。单实现可以优化,多实现就没法了。JVM是通过保存虚函数表Virtual Method Table(以下称为VMT)存储class对象中所有的虚函数 - 逃逸分析:。锁消除基于逃逸分析的。栈上分配逃逸分析能判断对象是否逃逸,然后将对象分配到栈上,不过Hotspot虚拟机,并没有进行实际的栈上分配,而是使用了标量替换这一技术。
- Loop Transformations (循环展开)。它试图以牺牲程序二进制码大小为代价来优化程序的执行速度,是一种用空间换时间的优化手段。、循环分离:for循环内的一些场景放到外部去执行。
- 窥孔优化与寄存器分配 :。 这一步就是就是指令优化了 乘转变右移。
实战参数
编译相关的重* 要参数
-XX:+TieredCompilation:开启分层编译,JDK8之后默认开启
-XX:+CICompilerCount=N:编译线程数,设置数量后,JVM会自动分配线程数,C1:C2 = 1:2
-XX:TierXBackEdgeThreshold:OSR编译的阈值
-XX:TierXMinInvocationThreshold:开启分层编译后各层调用的阈值
-XX:TierXCompileThreshold:开启分层编译后的编译阈值
-XX:ReservedCodeCacheSize:codeCache最大大小
-XX:InitialCodeCacheSize:codeCache初始大小