概述
首先执行引擎是java虚拟机核心的组成部分之一;而JVM的主要任务是装载字节码到内存,但不能够直接运行在操作系统之上.因为字节码指令并非等价于本地机器指令,它仅仅包含能够被JVM所识别的指令、符号表、以及其他信息;而此时执行引擎就华丽登场,它的任务就是将字节码指令解释/JIT编译为对应平台上的本地机器指令,即将高级语言翻译为机器语言的执行者;执行引擎包含了解释器、JIT编译器、垃圾回收.
执行引擎执行流程
- 执行引擎从PC寄存器获取字节码指令
- 每次执行完成一条指令,PC寄存器就会更新下一条需要被执行的指令地址
- 在方法执行过程中,执行引擎也会通过存储在局部变量表中的对象引用地址定位到堆内存中的对象实例数据,以及通过对象头中的类型指针定位到方法区中的类型信息
执行分类:解释器和JIT编译
Java被称为半解释型和半编译型语言的原因就在于JVM中的执行引擎采用了解释器和JIT编译器结合方式执行.
- 橙色字体流程: .java源文件通过java前端编译器生成字节码.class文件的过程
- 绿色字体流程: 代表解释器流程,就是对字节码采用逐行解释的方式翻译为对应平台的机器指令
- 蓝色字体流程: 代表JIT编译器(也称为后端编译器),就是将源代码直接编译成对应平台的机器指令(JIT编译后的内容存储在方法区中)
编译器
- 前端编译器: 执行java源代码文件翻译为java字节码文件的过程
- JIT编译器: Just in time,执行将字节码文件翻译为机器指令过程,主要是将热点代码(一个被多次调用的方法或者方法内部存在循环次数较多的循环体)进行栈上替换;而Hotspot内置了两个JIT编译器,分别是C1和C2
- C1表示Client Compile,C1对字节码进行简单可靠地优化,耗时短,已达到更快的编译速度
- C2表示Server Compile,C2会进行耗时较长以及激进优化,但优化后的代码执行效率更高
- 我们可以通过命令指定JVM在运行时采取哪种编译器:-client和-server(JDK7后,我们可以指定-server命令开启分层编译,即会结合C1和C2来编译程序)
- AOT编译器: Ahead of Time,静态提前编译器,执行直接把java源代码翻译成机器指令的过程
执行模式
Hotspot默认采取的是解释和JIT混合模式,但也可单独指定执行模式:
- -Xint: 完全采用解释器模式
- -Xcomp: 完全采用JIT编译器模式,若JIT出现问题,则解释器会介入执行
- -Xmixed: 采用解释器和JIT混合模式
常见问题
JIT编译器执行效率如此高,而且JRocket就仅适用JIT,那Hotspot为何还要保留解释器呢?
解释器优势在于响应时间快,当程序启动后,直接解释执行字节码指令;而JIT编译器首先将字节码编译为机器指令,然后再执行指令,需要一定的编译时间;但HotSpot采取结合了两者优势执行程序:当JVM启动后,解释器可以首先发挥作用,而不需要等待JIT编译器全部编译完成后再执行,这样可以省去不必要的编译时间,随着时间推移,JIT编译器发挥作用,把越来越多的代码翻译为本地代码,获得更高的执行效率