侃侃编译器优化

32 篇文章 4 订阅
22 篇文章 2 订阅

字节码是如何运行的?

首先我们先探讨一下字节码是如何运行的,众所周知,java有两种运行模式,一种叫解释执行,一种叫编译执行:

  • 解释执行:由编译器一行一行翻译执行
  • 编译执行:把字节码翻译成机器码,直接执行机器码

下面我们来对比一下这两种执行模式:

  • 解释执行:
    • 优势在于没有编译的等待时间
    • 性能相对差一些
  • 编译执行:
    • 运行效率会高很多,一般认为比解释执行快一个数量级
    • 带来了额外开销

那么怎样去查询Java是解释执行还是编译执行的呢?
很简单,执行 java -version就可以了
在这里插入图片描述
我们可以看到有一个 mixed mode 表示混合模式,表示部分代码解释执行,部分代码编译执行。
你可以使用-Xint:把JVM的执行模式设置为解释执行模式
也可以使用 -Xcomp:JVM优先以编译模式运行,不能编译的,以解释执行模式运行。
也可以使用-Xmixed:让JVM以混个模式运行,默认情况下就是混合模式。

JVM如何优化解释器?

在一般情况下

  • 一开始由解释器解释执行
  • 当虚拟机发现某个方法或代码块的运行特别频繁的时候,就会认为这些代码是“热点代码”。为了提高热点代码的执行效率,会用即时编译器(也就是JIT)把这些热点代码编译成本地平台相关的机器码,并进行各层次的优化

就目前来说,Hostpot虚拟机内置了两个编译器,也就是C1编译器和C2编译器:

  • C1编译器:
    • 是一个简单快速的编译器
    • 主要关注局部性的优化
    • 适用于执行时间比较短或对启动性能有要求的程序。例如,GUI应用对界面启动速度就有一定的要求。
    • 也被称为Client Complier
  • C2编译器:
    • 是为长期运行的服务器端应用程序做性能调优的编译器
    • 适用于执行时间较长或对峰值性能有要求的程序
    • 也被称为是Server Complier

各层次优化指的是哪些优化?

从JDK7开始,正式引入了分层编译的概念,可以细分为五种编译级别

  • 0:解释执行
  • 1:简单C1编译:会用C1编译器进行简单优化,不开启profiling(JVM性能监控)
  • 2:受限的C1编译:仅执行带方法调用次数以及循环回边执行次数Profiling的C1编译
  • 3:完全C1编译:会执行带有所有Profiling的C1代码
  • 4:C2编译:使用C2编译器进行优化,该级别会启用一些编译耗时比较长的优化,一些情况下会根据性能监控信息进行一些非常激进的性能优化

一般来说级别越高,应用启动越慢,优化的开销越高,峰值性能也越高

分层编译-JVM参数配置

默认情况下,JDK8是开启分层编译的

  • 只想开启C2:-XX:-TieredCompilation(禁用中间编译层(123层))
  • 只想开启C1:-XX:+TieredCompilation -XX:TieredStopAtLevel=1

如何找到热点代码?

前面提到过,编译执行主要是针对热点代码的,那么如何找到这些热点代码呢?
就目前来说,业界对于找到热点代码的思路有两种

  1. 基于采样的热点探测
    大致思路是:周期检查各个线程的栈顶,如果某个方法经常出现在栈顶,那么就会认为这个方法是热点方法。
  2. 基于计数器的热点探测
    大致思路是为每个方法或者代码块建立计数器, 统计执行的次数,如果超过一定阈值,那么就会认为它是热点方法。

Hotspot虚拟机是采用的基于计数器的热点探测。

Hotspot内置的两类计数器

  • 方法调用计数器(Invocation Counter)
    • 用于统计方法被调用的次数,在不开启分层编译的情况下,在C1编译器下的默认阈值是1500次,在C2模式下是10000次。也可用-XX:CompileThreshold=X执行阈值
  • 回边计数器(Back Edge Counter)
    • 用于统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为"回边"(Back Edge)。在不开启分层编译的情况下,C1编译器下的默认阈值13995,C2默认为10700,可使用-XX:OnStackReplacePercentage=X指定阈值
    • 建立回边计数器的主要目的是为了触发OSR(OnStackReplacement)编译

当开启分层编译,JVM会根据当前待编译的方法数以及编译线程数来动态调整阈值,-XX: CompileThreshold、-XX:OnStackReplacePercentage都会失效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值