🕉️ 前端编译 & 优化

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

🕉️ 前端编译 & 优化

1. 前端编译

1) 编译:

  • 前端编译器: JDK 的 Javac
    • 几乎没有优化措施,对性能的优化主要集中在运行期的 JIT 中,这样可以使得非 Javac 产生的 Class 文件也可以享受到 JIT 优化的红利
  • 即时编译器: HotSpot 的 C1 & C2 编译器
  • 提前编译器

2) Javac 编译过程


2. 编译具体过程 & 相关优化

1) 词法分析 & 语法分析

  • 词法分析
    • int a = b + 2 分解成 int a = b + 2
  • 语法分析
    • 生成抽象语法树

2) 填充符号表

  • 符号表类似于 K-V 的哈希结构
  • 存放符号地址 & 符号信息
  • 若未提供任何构造函数,则默认构造函数在此时添加

3) 注解处理器

  • JDK 5 提供了对注解的支持,用于运行期间发挥作用
  • JKD 6 提供了插入式注解,可在编译期对特定注解进行处理,从而影响前端编译
  • 举例:
    • Lombok 通过注解自动生成 getter/setter equals() hashCode() 等方法

4) 语义分析

  • 标注检查
    • 变量使用前是否已被声明、变量与赋值之间的数据类型是否匹配
    • 常量折叠 int a = 1 + 2 转换成 int a = 3
  • 数据 & 控制流分析
    • 局部变量使用前是否被赋值
    • 每条方法路径是否有返回值
    • 所有受检异常是否被正确处理等

5) 解语法糖

  1. 泛型
    • 类型擦除式泛型
    • 只在程序源码中存在,在编译后的字节码文件中,被替换为原来的裸型,并在相应地方插入强制转换代码
  2. 变长参数
  3. 自动拆装箱
    • 包装类的 == 只有在遇到算术运算符时才会自动拆装箱
    • 包装类的 equals() 不处理数据类型的转换
  4. 遍历循环
    • 还原成 Iterator 的实现,因此要遍历的类必须实现 Iterator 接口

6)字节码生成

  • 将语法树 & 符号表转换成字节码指令写入磁盘
  • 进行少量代码添加 & 转换
    • 添加实例构造器 <init>() & 类构造器 <clinit>()

3. 字节码

  • 字节码属于 .Class 文件的一部分,具体为 Class 文件的方法表中的 Code 属性
上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou