《深入理解Java虚拟机》十:早期(编译器)优化

现在Java虚拟机团队把性能的优化集中到了后端的即时编译器.
前期的优化,主要做了针对Java语言编码过程的优化措施来改善程序员的编码风格和提高编码效率。

大纲

早期编译器优化

概述

Java语言的“编译期”其实是一段“不确定”的操作过程,编译期比较有代表性的编译期有3类:

  • 前端编译器(编译器的前端)
    • .java文件转变成.class文件的过程
    • Sun的Javac、EclipseJDT中的增量式编译器
  • JIT编译器(后端运行期编译器)
    • 虚拟机的后端运行期编译器,把字节码转变为机器码的过程
    • HotSpot VM的C1、C2编译器
  • AOT编译器(静态提前编译器)
    • 静态提前编译器,把*.java文件编译成本地机器码代码的过程
    • GNU Complier for the Java(GCJ)、Excelsior JET

Javac编译器

编译过程

Javac的编译过程

编译过程大致可以分为3个过程,分别为:

  1. 解析与填充符号表过程
  2. 插入式注解处理器的注解处理过程
  3. 语义分析与字节码生成过程

Javac编译过程的主体代码

Snipaste_2018-07-23_08-32-48

解析与填充符号表过程

解析

  1. 词法分析:将源代码的字符流转变为标记(Token)集合
  2. 语法分析:根据Token序列构造抽象语法树的过程

填充符号表

符号表是由一组符号地址和符号信息构成的表格,填充符号表的过程是一个待处理列表,包含了每一个编译单元的抽象语法树的顶级节点。

插入式注解处理器的注解处理过程

在JDK1.5之后,Java语言提供了对注解(Annotation)的支持,这些注解与普通的Java代码一样,是在运行期间发挥作用的。在JDK1.6中实现提供了插入式注解处理器的API(可以看做是一组编译器的插件)在编译期间对注解进行处理。
如果这些插件在处理注解期间对语法树进行了修改,编译器将回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止,每一次循环称为一个Round。

语义分析与字节码生成过程

  1. 语义分析:对结构上正确的源程序进行上下文有关性质的审查
    • 标注检查
      标注检查步骤检查的内容包括诸如变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配等。在标注检查步骤中,还有一个重要的动作称为常量折叠
    • 数据及控制流分析
      数据及控制流分析是对程序上下文逻辑更进一步的验证,它可以检查出诸如程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了等问题
  2. 解语法糖
    泛型、变长参数、自动装箱/拆箱等语法,虚拟机运行时是不支持的,需要在编译阶段还原简单的基础语法结构,这个过程称为接语法糖。
  3. 字节码生成

Java语法糖的味道

  • 泛型与类型擦除
  • 自动装箱、拆箱与遍历循环
  • 条件编译

公众号:亦袁非猿

欢迎关注,交流学习