java虚拟机基础知识大全 java虚拟机运行原理( 十 )


跨越JDK版本之间的沟壑,把高版本JDK中编写的代码放到低版本JDK环境中去部署使用 。为了解决这个问题,一种名为“Java逆向移植”的工具(JavaTools)应运而生,[插图]和是这类工具中的杰出代表 。
JDK的每次升级新增的功能大致可以分为以下五类:
1)对Java类库API的代码增强 。譬如JDK 1.2时代引入的java.util.等一系列集合类,在JDK 5时代引入的java.util.并发包、在JDK 7时引入的java.lang.包,等等 。
2)在前端编译器层面做的改进 。这种改进被称作语法糖,如自动装箱拆箱,实际上就是Javac编译器在程序中使用到包装对象的地方自动插入了很多.()、Float.()之类的代码;变长参数在编译之后就被自动转化成了一个数组来完成参数传递;泛型的信息则在编译阶段就已经被擦除掉了(但是在元数据中还保留着),相应的地方被编译器自动插入了类型转换代码[插图] 。
3)需要在字节码中进行支持的改动 。如JDK 7里面新加入的语法特性——动态语言支持,就需要在虚拟机中新增一条字节码指令来实现相关的调用功能 。不过字节码指令集一直处于相对稳定的状态,这种要在字节码层面直接进行的改动是比较少见的 。
4)需要在JDK整体结构层面进行支持的改进,典型的如JDK 9时引入的Java模块化系统,它就涉及了JDK结构、Java语法、类加载和连接过程、Java虚拟机等多个层面 。
5)集中在虚拟机内部的改进 。如JDK 5中实现的JSR-133[插图]规范重新定义的Java内存模型(JavaModel,JMM),以及在JDK 7、JDK 11、JDK 12中新增的G1、ZGC和收集器之类的改动,这种改动对于程序员编写代码基本是透明的,只会在程序运行时产生影响 。
前端编译器(叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;
Java虚拟机的即时编译器(常称JIT编译器,Just In Time )运行期把字节码转变成本地机器码的过程;
指使用静态的提前编译器(常称AOT编译器,Ahead Of Time ) 。
Java中即时编译器在运行期的优化过程,支撑了程序执行效率的不断提升;而前端编译器在编译期的优化过程,则是支撑着程序员的编码效率和语言使用者的幸福感的提高 。
编译——1个准备3个处理过程
1)准备过程:初始化插入式注解处理器 。
2)解析与填充符号表过程,包括:·词法、语法分析 。将源代码的字符流转变为标记集合,构造出抽象语法树 。·填充符号表 。产生符号地址和符号信息 。
3)插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段,本章的实战部分会设计一个插入式注解处理器来影响Javac的编译行为 。
4)分析与字节码生成过程,包括:·标注检查 。对语法的静态信息进行检查 。·数据流及控制流分析 。对程序动态运行过程进行检查 。·解语法糖 。将简化代码编写的语法糖还原为原有的形式 。·字节码生成 。将前面各个步骤所生成的信息转化成字节码 。
执行插入式注解时又可能会产生新的符号,如果有新的符号产生,就必须转回到之前的解析、填充符号表的过程中重新处理这些新符号
插入式注解处理器看作是一组编译器的插件,当这些插件工作时,允许读取、修改、添加抽象语法树中的任意元素 。如果这些插件在处理注解期间对语法树进行过修改,编译器将回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止,每一次循环过程称为一个轮次(Round) 。
语义分析与字节码生成
1.标注检查
标注检查步骤要检查的内容包括诸如变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配 。