🕎 后端编译 & 优化

吞佛童子2022年6月20日
  • Java
  • JVM
大约 2 分钟

🕎 后端编译 & 优化

1. 即时编译器

1) 作用

  • HotSpot & J9 中,Java 程序最初都是通过解释器进行解释执行的
  • 当虚拟机发现某个方法 | 代码块的运行特别频繁时,就会将这些代码认定为 热点代码
  • 为提高热点代码的执行效率,在运行时,虚拟机会将这些代码编译本地机器码,并用各种手段进行代码优化
  • 完成这个任务的后端编译器就是即时编译器

2) 编译器 VS 解释器

  • 编译器执行效率快,启动慢,占内存资源
  • 解释器节约内存,启动快,执行效率较低

3) HotSpot 即时编译器

  1. HotSpot 内置 2 个 | 3 个即时编译器
    • C1 编译器 - 客户端编译器 - 编译速度快,进行简单优化编译质量较差
    • C2 编译器 - 服务端编译器 - 编译耗时长,进行高复杂度优化算法,编译质量好
    • JDK 10 出现的 Opto 编译器
  2. 编译对象
    • 被多次调用的方法
    • 被多次执行的循环体
  3. 触发条件判断
    • 基于 采样 的热点探测
      • 应用于 J9
      • 虚拟机周期性检查各个线程的调用栈顶,若发现某个方法经常出现在栈顶,则为热点方法
      • 特点:
        • 简单高效
        • 易受到线程阻塞 | 别的外界因素影响探测
    • 基于 计数器 的热点探测
      • 应用于 HotSpot
      • 为每个方法建立计数器,统计方法的执行次数,超过某个阈值,则为热点方法
      • 特点:
        • 为每个方法建立并维护计数器,实现较复杂
        • 统计结果更加精确

2. 提前编译器

2 个分支

  • 与 C++ 类似,在程序运行之前将程序代码编译成本地机器码
  • 将原本 JIT 的编译工作提前做好并保存下来,下次运行这些代码时可以直接加载并使用

3. 编译器优化技术

1) 逃逸分析

① 三种逃逸

  • 从不逃逸 🍭🍭🍭
  • 方法逃逸 🍭🍭
    • 当一个对象在方法里被定义后,可能被外部方法所引用
  • 线程逃逸 🍭
    • 当一个对象在方法里被定义后,可能被外部线程访问到

② 逃逸优化

  • 栈上分配
    • 若对象不会逃逸出线程之外,则可以在栈上分配
    • 支持 从不逃逸 方法逃逸
  • 同步消除
    • 若发现某个变量不会逃逸出线程,则对该变量施加的同步措施可以进行消除
    • 支持 从不逃逸 方法逃逸
  • 标量替换
    • 将对象的成员变量恢复为原始数据类型来访问,此时不需要创建该对象
    • 支持 从不逃逸
上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou