🕎 后端编译 & 优化
2022年6月20日
- Java
🕎 后端编译 & 优化
1. 即时编译器
1) 作用
- 在
HotSpot
&J9
中,Java 程序最初都是通过解释器进行解释执行的 - 当虚拟机发现某个方法 | 代码块的运行特别频繁时,就会将这些代码认定为 热点代码
- 为提高热点代码的执行效率,在运行时,虚拟机会将这些代码编译成本地机器码,并用各种手段进行代码优化,
- 完成这个任务的后端编译器就是即时编译器
2) 编译器 VS 解释器
- 编译器执行效率快,启动慢,占内存资源
- 解释器节约内存,启动快,执行效率较低
3) HotSpot 即时编译器
- HotSpot 内置 2 个 | 3 个即时编译器
- C1 编译器 - 客户端编译器 - 编译速度快,进行简单优化编译质量较差
- C2 编译器 - 服务端编译器 - 编译耗时长,进行高复杂度优化算法,编译质量好
- JDK 10 出现的 Opto 编译器
- 编译对象
- 被多次调用的方法
- 被多次执行的循环体
- 触发条件判断
- 基于 采样 的热点探测
- 应用于 J9
- 虚拟机周期性检查各个线程的调用栈顶,若发现某个方法经常出现在栈顶,则为热点方法
- 特点:
- 简单高效
- 易受到线程阻塞 | 别的外界因素影响探测
- 基于 计数器 的热点探测
- 应用于 HotSpot
- 为每个方法建立计数器,统计方法的执行次数,超过某个阈值,则为热点方法
- 特点:
- 为每个方法建立并维护计数器,实现较复杂
- 统计结果更加精确
- 基于 采样 的热点探测
2. 提前编译器
2 个分支
- 与 C++ 类似,在程序运行之前将程序代码编译成本地机器码
- 将原本 JIT 的编译工作提前做好并保存下来,下次运行这些代码时可以直接加载并使用
3. 编译器优化技术
1) 逃逸分析
① 三种逃逸
- 从不逃逸 🍭🍭🍭
- 方法逃逸 🍭🍭
- 当一个对象在方法里被定义后,可能被外部方法所引用
- 线程逃逸 🍭
- 当一个对象在方法里被定义后,可能被外部线程访问到
② 逃逸优化
- 栈上分配
- 若对象不会逃逸出线程之外,则可以在栈上分配
- 支持 从不逃逸 方法逃逸
- 同步消除
- 若发现某个变量不会逃逸出线程,则对该变量施加的同步措施可以进行消除
- 支持 从不逃逸 方法逃逸
- 标量替换
- 将对象的成员变量恢复为原始数据类型来访问,此时不需要创建该对象
- 支持 从不逃逸