JVM——后期编译和代码优化

引入

该博文是我JVM——程序编译优化之早期编译优化的一篇后续博文,该博文主要介绍后期编译(JIT)也称为即时编译的细节和它的优化体现。在介绍之前我们需要知道在没有后期编译器时JAVA程序全都是靠着解释器去解释生成的class文件执行这一知识点

解释器和后期编译器

既然JAVA程序靠的是解释器去执行那么解释器和后期编译器的关系或者它们的运行关系是如何的。其实对于后期编译器而言JAVA虚拟机没有规定其是必须存在同时也没有它的实现规范,所以这一切的存在与否全是虚拟机自身的实现。一般而言(针对主流),虚拟机中同时存在解释器和后期编译器,而它们的运行关系即使互相配合工作。而它们的互相配合工作可以分为三种不同的情况(模式):混合模式解释模式编译模式
混合模式:其实就是说解释器和编译器一起工作运转来配合使用
解释模式:就是说此时没有编译器工作全是解释器来解释运行JAVA程序
编译模式:就是说编译器会即时编译class文件为本地平台代码来执行,但同时解释器也会在运转,用于帮助编译器收集性能监控数据。
在说完了三种模式后,还要有一个概念就是说解释器对于程序的响应快、占用内存少、而编译器由于要优化和编译为本地的机器码所以会占用用户程序的时间,因此对于程序响应慢,占用内存多等特点

后期编译触发条件和编译对象

既然说到了后期编译,那么就要涉及两个问题:
1、触发后期编译的条件
2、被编译的对象
针对上面的两个问题,有如下的说明:
1)被编译的对象
其实就是JVM会通过热点探测(Hot spot Detection)来获取到热点代码,即需要被编译的对象,细分的话又可以分为热点方法和多次循环执行的循环体;虽然一个是方法,另外一个是多次循环执行的循环体但是他们在编译是都是以方法作为被编译对象去编译
2)触发后期编译的条件
说到触发条件就要说到热点探测的方法,JVM中有如下的两种探测方法:
1、基于样本的热点探测(Samped Based Hot Spot Detection),就是JVM会定期的去检查每个线程中的虚拟机栈中的栈顶的方法,通过探测发现,方法多次都在栈顶,那么该方法就是热点方法,但该探测的手段,容易受到线程阻塞和其他的外界影响
2、基于计数器的热点探测,其实就是JVM为每个方法甚至代码块都维护了一个计数器,但计数器的值超过了某一个阈值那么就触发了后期编译的条件。而该计数器分为:方法调用计数器和回边计数器,其实这两种计数器就是针对不同的热点代码场景,一个是方法,一个是多次执行的循环体。在具体说明这两种计数器时还要说明一个概念就是说对于被编译的对象本身就是一个方法时, 那么此刻进行的优化就是JIT标准的即时编译,而对于被编译的对象是因为方法内部的多次循环体代码而要优化整个方法的情况,这种编译称为OSR编译,因为此刻方法已经处于运行中在虚拟机的栈上了。
方法调用计数器:就是当一个方法执行时先看该方法有没有被后期编译过有那么就执行被后期编译后生成的字节码,如果没有那么就用解释器执行,并把该方法的调用计数器加1,然后检查该方法的调用计数器和回边计数器的和超过调用计数器的阈值,超过了就发出标准的JIT编译的请求,然后如果没有别的动作那么JVM执行引擎就会用解释器继续执行该方法,执行完后修改该方法的内存访问地址到被编译后生成的对应的机器码版本的方法入口。如果没有超过阈值那么还是用解释器执行方法只是说后续没有那超过后的那些动作。
对于方法调用计数器还需要说明的是该计数器并不是记录的是该方法真实的调用次数,而是被调用的频率,即在一段时间内的调用次数,因为如果该方法在一段时间(半衰期)内计数器之和没有超过方法调用计数器之和那么该方法对应的方法调用计数器的值就会被减少一半,称为热点衰减。
回边计数器:即当JVM遇到回边指令的时候(可以理解为遇到循环),会检查该方法对应的代码片段是否存在以及被编译后的版本存在就执行被编译后的版本,如果不存在那么就调用解释器执行JAVA代码,把该方法的回边计数器加1,检查该方法的回边计数器和调用计数器之和是否超过回边计数器的阈值,超过了就申请OSR编译请求然后减少回边计数器的值,继续用解释器执行方法。之后仍然会修改该方法的内存地址。如果没有超过阈值那么就还是用解释器执行,只是不修改内存地址。
而对于回边计数器而言不存在方法调用计数器的热点衰减,它记录的是方法内部的循环代码块的真实的执行次数,当回边计数器的值溢出的时候它也会把该方法的方法调用计数器的值溢出,以便下次调用该方法的时候采用标准的后期编译而不是OSR后期编译*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值