JVM - 执行引擎

1. 概述

虚拟机是一个相对物理机的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是建立在处理器,缓存,指令集和操作系统层面上的,而虚拟机执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集和执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式

JVM的主要任务是负责装载字节码到期内部,但是字节码并不能直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅是一些能够被JVM所识别的字节码指令,符号表,以及其他辅助信息

为了让一个Java程序跑起来,执行引擎的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以,简单来说,JVM中的执行引擎充当了将高级语言翻译为机器语言的译者
JVM - 执行引擎
注意这里需要区分一下:
Java的编译期其实是一段不确定的操作过程,一共有三种

  • 前端编译器(叫编译器的前端更准确)把*.java文件转换为*.class文件的过程,前端编译器有SunJavacEclipse JDT中的增量式编译器等
  • 后端运行期编译器(JIT编译器,Just In Time Compiler)把字节码转换为机械码的过程,主要有HotSpot VMC1C2编译器
  • 静态提前编译器(AOT编译器,Ahead Of Time Compiler)直接把*.java文件编译成本地机械码的过程,有GCN Compiler for the java

这里说的执行引擎是在说后两种

执行引擎在执行的过程中需要执行什么样的字节码指令依赖于程序计数器

2. Java代码编译和执行过程

JVM - 执行引擎
对于前端编译器生成的线性的字节码指令流,有两种选择;
java是半编译半解释性语言,也就是说即可以通过解释器逐行解释执行,也可以通过编译器编译成对应的机器指令

2.1 解释器

这里关于Java语言跨平台的特性有一个问题:

Java语言之所以能够跨平台是因为Java的源程序被编译生成字节码文件,字节码文件又被不同平台的JVM解释成对应平台的机器指令,苍从而实现了跨平台的特性;但是,中间为什么需要一步源程序到字节码文件的转换呢?为什么不直接将Java程序交给不同平台的JVM解释成对应平台的机器指令?

网上说是这样降低了JVM的压力,把解释分为了前端解释器生成字节码文件,再让JVM只根据字节码生成机器指令,更快

当Java虚拟机启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容翻译为对应平台的本地机器指令直接执行

现在这种解释器执行的方式被视为低效的代名词,为了解决这个问题,JVM平台支持了即时编译的功能;
即时编译的目的是避免函数被解释执行,而是将整个函数编译成为机器码,每次函数执行时,只执行编译后的机器嘛即可,也就是说,有一定的缓存作用

2.2 JIT编译器

虚拟机将方法编译成机器码,缓存起来,之后再要执行这个方法就直接去找缓存起来的机器码,更为高效,在编译的过程也可以进行优化

为什么选择解释器和编译器共存
为了各自的取长补短,在程序刚启动的时候,解释器马上可以发挥作用,省去编译的时间,响应的速度快;随着程序运行时间的推移,即时编译器逐渐发挥作用,根据热点探测功能,将有价值的字节码编译成本地机器码,以换取更改的程序执行效率

2.3 AOT编译器

比起JITAOT是在程序运行之前,将字节码转换为机器码