🕎 后端编译 & 优化
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) 逃逸分析
① 三种逃逸
- 从不逃逸 🍭🍭🍭
 - 方法逃逸 🍭🍭 
- 当一个对象在方法里被定义后,可能被外部方法所引用
 
 - 线程逃逸 🍭 
- 当一个对象在方法里被定义后,可能被外部线程访问到
 
 
② 逃逸优化
- 栈上分配
- 若对象不会逃逸出线程之外,则可以在栈上分配
 - 支持 从不逃逸 方法逃逸
 
 - 同步消除
- 若发现某个变量不会逃逸出线程,则对该变量施加的同步措施可以进行消除
 - 支持 从不逃逸 方法逃逸
 
 - 标量替换
- 将对象的成员变量恢复为原始数据类型来访问,此时不需要创建该对象
 - 支持 从不逃逸