例如:
a=100;b=200;c=300;return (a+b)*c
javap提示这段代码需要深度为2的操作数栈和4个变量槽的局部变量空间

代码编译和优化
Tomcat的类加载

OSGi(Open Service Gateway Initiative)是OSGi联盟(OSGi Alliance)制订的一个基于Java语言的动态模块化规范(在JDK 9引入的JPMS是静态的模块系统)
字节码生成技术与动态代理的实现
字节码生成技术应用于:javac,Web服务器中的JSP编译器,编译时织入的AOP框架,还有很常用的动态代理技术,甚至在使用反射的时候虚拟机都有可能会在运行时生成字节码来提高执行速度。
动态代理中所说的“动态”,是针对使用Java代码实际编写了代理类的“静态”代理而言的,它的优势不在于省去了编写代理类那一点编码工作量,而是实现了可以在原始类和接口还未知的时候,就确定代理类的代理行为,当代理类与原始类脱离直接联系后,就可以很灵活地重用于不同的应用场景之中。
跨越JDK版本之间的沟壑,把高版本JDK中编写的代码放到低版本JDK环境中去部署使用。为了解决这个问题,一种名为“Java逆向移植”的工具(Java Backporting Tools)应运而生,Retrotranslator[插图]和Retrolambda是这类工具中的杰出代表。
JDK的每次升级新增的功能大致可以分为以下五类:
1)对Java类库API的代码增强。譬如JDK 1.2时代引入的java.util.Collections等一系列集合类,在JDK 5时代引入的java.util.concurrent并发包、在JDK 7时引入的java.lang.invoke包,等等。
2)在前端编译器层面做的改进。这种改进被称作语法糖,如自动装箱拆箱,实际上就是Javac编译器在程序中使用到包装对象的地方自动插入了很多Integer.valueOf()、Float.valueOf()之类的代码;变长参数在编译之后就被自动转化成了一个数组来完成参数传递;泛型的信息则在编译阶段就已经被擦除掉了(但是在元数据中还保留着),相应的地方被编译器自动插入了类型转换代码[插图]。
3)需要在字节码中进行支持的改动。如JDK 7里面新加入的语法特性——动态语言支持,就需要在虚拟机中新增一条invokedynamic字节码指令来实现相关的调用功能。不过字节码指令集一直处于相对稳定的状态,这种要在字节码层面直接进行的改动是比较少见的。
4)需要在JDK整体结构层面进行支持的改进,典型的如JDK 9时引入的Java模块化系统,它就涉及了JDK结构、Java语法、类加载和连接过程、Java虚拟机等多个层面。
5)集中在虚拟机内部的改进。如JDK 5中实现的JSR-133[插图]规范重新定义的Java内存模型(Java Memory Model,JMM),以及在JDK 7、JDK 11、JDK 12中新增的G1、ZGC和Shenandoah收集器之类的改动,这种改动对于程序员编写代码基本是透明的,只会在程序运行时产生影响。
编译的概念
前端编译器(叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;
Java虚拟机的即时编译器(常称JIT编译器,Just In Time Compiler)运行期把字节码转变成本地机器码的过程;
指使用静态的提前编译器(常称AOT编译器,Ahead Of Time Compiler)。
Java中即时编译器在运行期的优化过程,支撑了程序执行效率的不断提升;而前端编译器在编译期的优化过程,则是支撑着程序员的编码效率和语言使用者的幸福感的提高。
编译——1个准备3个处理过程
1)准备过程:初始化插入式注解处理器。
2)解析与填充符号表过程,包括:·词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树。·填充符号表。产生符号地址和符号信息。
3)插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段,本章的实战部分会设计一个插入式注解处理器来影响Javac的编译行为。
4)分析与字节码生成过程,包括:·标注检查。对语法的静态信息进行检查。·数据流及控制流分析。对程序动态运行过程进行检查。·解语法糖。将简化代码编写的语法糖还原为原有的形式。·字节码生成。将前面各个步骤所生成的信息转化成字节码。
执行插入式注解时又可能会产生新的符号,如果有新的符号产生,就必须转回到之前的解析、填充符号表的过程中重新处理这些新符号