1.2 tiered compilation(分层编译)

五个级别

  前文讲过,编译器分c1和c2两种,c1适合客户端,启动速度快,但是编译后的代码质量不高。C2适合服务端,启动速度慢,占用内存高,但是编译后的代码质量高,执行效率高。在JDK8以前,使用-client可以激活C1编译器,-server可以激活C2编译器。但是JDK8及以后的版本这个就没用了。
  那有没有中间方案呢?JDK7开始,出现了混合模式编译,也就是分层编译技术。分层编译技术不仅Java有,Java的竞争对手.Net也有分层编译技术。
  Java的分层编译将编译定义为五个级别:

级别策略
0解释器执行
1无任何监控模式的C1编译器
2带方法调用和回边计数器的C1编译器
3完全监控模式(MDO)的C1编译器
4C2编译器

  对于level 1~3,很多博文没解释清楚,我解释一下。解释器是肯定带方法调用和回边计数器的。但是C1编译器可以带,也可以不带。所以level 1,level 2和level 3。性能最高的是level 1,因为不监控任何数据,性能最差的是level 3。所以他们的性能是level 4 > level 1 > level 2 > level 3 > level 0。但是因为level 1没有任何监控,所以它不可能有触发机制到达level 4,除非反优化,level 1将是终态。
  更需要注意的编译级别的切换不是整个虚拟机的级别切换,而是某个方法的级别切换。在虚拟机运行过程中,一个程序流程,调用了很多方法,这里面有些方法是解释器运行,有些是编译器运行。所以编译级别是方法的属性,也不是线程的属性,更不是虚拟机的属性。

级别切换

  通常情况: 0 → 3 → 4 0 \to 3 \to 4 034
  C2队列满: 0 → 2 → 3 → 4 0 \to2\to 3 \to 4 0234。这里我解释一下。因为level 3的目的是完全监控,然后用监控数据去进行C2编译。因为C2队列满了,所以不仅level4的方法不能再增加,level 3的方法也不能继续增加,所以level 0就直接编译为level 2。等C2队列空闲的时候,level 2的方法又调整为level 3。
  C2队列满,已经在队列里的变成2: 3 → 2 3\to2 32。这里我解释一下,因为C2队列满了,所以已经在队列里的level 3临时改变目标,编译为level 2。
  禁用了C2或者方法体过于简单: 0 → 2 → 1 0 \to 2 \to 1 021
  禁用了C2或者方法体过于简单: 0 → 3 → 1 0 \to 3 \to 1 031
  解释器完全监控模式: 0 → 4 0 \to4 04
  反优化: ( 1 , 2 , 3 , 4 ) → 0 (1,2,3,4)\to0 (1,2,3,4)0
  为此,我画了一张图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醒过来摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值