《深入理解Java虚拟机》 编译 & 优化

Java的编译过程可以分为两个阶段,首先是将.java文件编译为.class文件的过程,称为前端编译,比如javac;然后在运行期,可能即时编译器(JIT)又会将字节码转变为本地机器码,比如HotSopt的C1、C2编译器,或者Graal编译器。

对于优化处理,Java虚拟机团队选择将性能优化的措施全部集中在运行期的即时编译器中,以便让那些不是由 javac 产生的 Class 文件也能享受到性能优化的好处,至于 javac 中则做了一些针对Java语言编码过程的优化,用来降低开发者的编码复杂度、提高编码效率。可以这样认为,即时编译器在运行期的优化过程,支撑了程序执行效率的不断提升,而javac在编译期的优化过程,则支撑了开发者的编码效率和语言使用者的体验。

《深入理解Java虚拟机》 动态类型语言支持

Java虚拟机的字节码指令集自Sun公司推出第一款Java虚拟机至今,二十余年间只新增过一条指令,它就是随着JDK 7一起发布的 invokedynamic 指令。这条新增指令是JDK 7的项目目标:实现动态类型语言支持而进行的改进之一,也是为JDK 8中可以顺利实现 Lambda 表达式而做的技术储备。

《深入理解Java虚拟机》 字节码指令

Java虚拟机的指令由一个字节长度(0 ~ 255)、代表着某种特定操作含义的数字(操作码),以及其后跟随的零至多个参数(操作数)构成。由于Java虚拟机采用面向操作数栈而不是面向寄存器的架构,所以大多数指令都不包含操作数,只有一个操作码,指令参数都存放在操作数栈中。

采用一个字节来代表操作码,也是为了尽可能获得短小精干的编译代码,这种追求尽可能小数据量、高传输效率的设计,也是由于Java语言设计之初,主要面向网络、智能家电的技术背景所决定的,并一直沿用至今。

《深入理解Java虚拟机》 类 & Class对象/反射

在类加载成功之后,便以Class对象的形式保存在内存中。可以将Class对象理解成实例对象的元数据,通过Class对象中描述的类型信息,便可以创建对应的实例对象,从而进行方法调用,以及字段修改。那么,便可以通过反射根据运行时获取的类型信息来创建实例,而且可以跳过访问权限的限制访问字段和方法