《深入理解JVM》第11章后端编译与优化——即时编译器(JIT)

概述

所谓后端编译就是指从Class字节码编译为本地机器的二进制码的过程。
其中包括了提前编译器(AOT)和即时编译器(JIT).
这部分是评判一款虚拟机优秀与否的关键指标之一。

即时编译器

Java程序最初都是通过解释器执行的,当虚拟机发现某个方法执行得特别频繁时,就认定它们为热点代码,为了提高热点代码的执行速度,就会把他们编译为本地机器码,执行这些操作的就是即时编译器

解释器与编译器

在主流JVM中,都是解释器与编译器共存的。
解释器的优势是:不需要额外执行编译过程就可以立即运行。
编译器的作用:它会将一些使用频繁的代码(热点代码),编译为本地字节码,来减少中间消耗,获得较高的执行效率。

不过一些内存较为限制的场景下,也可能只使用解释器而不使用编译器(也可用 -Xint /-Xcomp指定仅解释器/编译器),解释器还可以作为激进优化(可能出错的情况,但是能够提升效率的场景选择优化)编译器时的后备逃生门(条件允许情况下,不那么激进的编译器也可作为逃生门),
在这里插入图片描述
由于即时编译器编译本地代码本身是需要占用程序运行时间的,而且可能需要解释器替编译器收集性能监控信息,这对解释执行期间也会产生影响。
所以便从直接搭配的工作方式转变为分层编译(JDK6基本实现(需要用-XX:TieredCompilation参数手动开启),JDK7为服务端模式JVM默认策略)
分层编译根据编译器编译、优化的规模与耗时,划分为不同的编译层次。

  • 0:程序纯解释,解释器不开启性能监控功能
  • 1:使用客户端编译器将字节码编译为本地代码来运行,进行简单可靠的优化,不开启性能监控功能
  • 2:使用客户端编译器,仅开启方法及回边(从循环边界往回跳转)次数统计等有限的性能监控
  • 3:客户端编译器全面开启性能监控,还会收集分支跳转,虚方法调用版本等全部统计信息。
  • 4:使用服务器编译器,会根据监控信息进行一些不可靠激进优化

层次转换图如下所示(来源):
在这里插入图片描述

编译对象与触发条件

主要分为两部分:

  • 被多次调用的方法
  • 被多次执行的循环体(编译的仍是循环体所属方法,不过不过会传入执行入口点紫萼解码序号(CBI),这种在方法栈帧仍在栈上,方法就被替换,形象的被称为栈上替换)

那么多次如何定义?

  • 基于采样的热点探测:周期性检查栈顶,如果发现某些方法经常出现在栈顶便是热点方法。(简单高效可获得调用关系,但很难精确的确认一个方法的热度,易受线程阻塞等因素的影响)
  • 基于计数器的热点探测 (HotSpot采用的方式),为每个方法体/代码块 创建计数器,统计计数器次数,如果执行次数超过预定的阈值则认为为热点(稍微复杂,不能直接获取调用关系,每个方法都需要维护一个计数器,但是精确)
    在HotSpot中每个方法维护了两个计数器(方法计数器和回边计数器,一旦值溢出,则触发JIT)

当发生JIT时,执行引擎是不会同步等待的,而是继续按照解释器执行字节码,不过当编译完成后,该方法的调用入口便会被系统自动替换为新值。

客户端方法调用计数器判定流程:
方法计数器:客户端默认1500,服务器默认10000,可用-XX:CompileThreshold设定,不过不是绝对的,有个热度衰减的概念,如果超过一定的时间内仍未达到目标次数,则减半
在这里插入图片描述
客户端回边计数器判定流程:

注意回边计数器没有热度衰减的过程。
**客户端回边次数的计算方式:**以方法调用计数器阈值(-XX:CompileThreshold)乘以OSR比率(-XX:OnStackReplacePercentage(默认值为933))除以100.如果都取默认值,则为13995.
服务器回边次数的计算方式: 法调用计数器阈值(-XX:CompileThreshold)乘以OSR比率(-XX:OnStackReplacePercentage(默认值为933))减去解释器监控比率(-XX:InterpreterProfilePercentage 默认为33)除以100.如果均为默认值,则为10700.

当回边计数器溢出时,也会把方法计数器调整到溢出状态。
在这里插入图片描述

编译过程

在允许后台编译的场景下,在编译完全前,JVM仍会按照解释的方式执行。可是如果关闭(-XX:-BackgroundCompilation),则会被阻塞等待编译完成,再运行,并执行编译器输出的本地代码。

客户端:

它是个简单快速三段式编译器,它放弃了许多耗时较长的全局优化,关注局部优化

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值