JVM--前端编译与优化--大致总结

编译器分类

前端编译器:javac之类,将java代码编译成字节码
即时编译器:Hotspot的C1、C2等,运行期间把字节码编译成本地代码
提前编译器:直接把java代码编译成字节码。

javac编译过程

(1)准备过程:初始化插入式注解处理器
(2)解析与填充符号表过程。包括:

  • 词法解析:将源码中的字符流转换为标记集合的过程。
  • 语法解析:根据标记序列构造出抽象语法树的过程,它的每个节点都代表一个语法结构。
  • 填充符号表:符号表是由一组符号地址和符号信息构成的数据结构,它所登记的内容用于语义检查和产生中间代码,在目标代码生成阶段,对符号进行地址分配时,符号表是地址分配的直接依据。

(3)插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段。

  • 允许读取、修改、添加抽象语法树中的任意元素。如果在处理注解期间对语法树进行过修改,编译器将回到解析和填充符号表的过程重新处理。
  • 著名的Lombok就是通过注解来实现自动生产getter/setter方法、进行空置检查、生成受查异常表、产生equals()和hashCode()等。

(4)语义分析与字节码生成过程。包括:

  • 标注检查。对语法的静态信息进行检查。包括变量使用前是否被声明、变量与赋值之间的数据类型是否能够匹配等。它还有一个常量折叠的一个优化,如a=1+2会优化成a=3。
  • 数据流及控制流分析。它是对程序上下问逻辑更进一步的验证,它可以检查出诸如程序局部变量在使用前是否赋值、方法的每条路径是否有返回值、是否所有的受查异常读被正确处理等。如方法中的final属性就是在该阶段进行检查,因为局部变量的标志不会被Class文件保存,加载的验证阶段无法进行检查。
  • 解语法糖。将简化代码编写的语法糖还原成原有的形式。如泛型、自动拆箱装箱、变长参数等
  • 字节码生成。将前面各个步骤所生成的信息转化成字节码。编译器还进行了少量的代码添加和转换工作,如实例构造器<init>和类构造器<cinit>方法都是在该阶段添加的。编译器会把变量初始化、语句块等操作收敛到构造方法中(<init>方法调用父类的实例构造器,<cinit>则不用调用父类的类构造器,因为虚拟机会保证其父类会加载进入)。

注意:第三阶段可能会产生新的符号,如果有新的符号产生,就必须转回第二阶段重新处理新的符号。

泛型

  • 泛型的本质是参数化类型或参数化多态的应用,即将其操作的数据类型指定为方法签名中的一种特殊参数,这种参数类型能够用在类、接口和方法的创建中,分别构成泛型类、泛型接口和泛型方法。
  • java泛型的实现方式叫做“类型擦除式泛型”,也就是在编译后的字节码文件中,全部泛型都被替换为原来的裸类型,并在相应的地方插入了强制转型代码,如ArrayList<Integer>与ArrayLIst<String>其实是同一种类型。
  • 在编译时把ArrayList<Integer>还原回ArrayList,只在元素访问、修改时自动插入一些强制类型转换和检查命令。因为基本类型无法转换成Object类,所以不能用基本类型而是使用其对应的包装类。

下面的类是无法通过编译的,因为List<String>和List<Integer>会被擦除变回List,导致这两个的方法特征签名一样。

public static void method(List<String> list){
}

public static void method(List<Ingeter> list){
}

条件编译

只有使用条件为常量的if语句才会进行条件编译

public static void main(String[] args){
    if(true){
        System.out.println("block1");
    } else {
        System.out.println("block2");
    }
)

该代码编译的字节码文件反编译后:

public static void main(String[] args){
    System.out.println("block1");
}

可以看到编译器会把分支中不成立的代码快消除掉。如果使用常量与其他带有条件判断能力的语句搭配,则可能在控制流分析中提示错误拒绝编译。如:

public static void main(String[] args){
    while (false) {
        System.out.println("");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值