写在最前,本篇文章大部分来源于b站尚硅谷JVM全套教程的提炼,并附带自己的理解。主要是为了帮助自己理解,和用于复习。如果同时还能对其他人有所裨益,那就更好不过了。如果有谬误的地方,还请不吝指出。
概述
执行引擎是jvm核心的组成部分之一
虚拟机是相对于物理机的概念,两者都有代码执行能力。
区别在于物理机的执行引擎直接建立在处理器、缓存、指令集和操作系统层面上,而虚拟机的执行引擎是由软件自行实现的。因此不受物理条件的限制,能执行不被硬件直接支持的指令集格式。
JVM主要任务是负责装载字节码到其内部,但字节码并不能直接运行在操作系统上,因为其不等同于本地机器指令。其仅包含能被JVM识别的指令、符号表。
如果想让java程序运行,执行引擎必须将字节码指令解释/编译为对应平台上的本地机器指令。即将高级语言翻译为机器语言。
工作过程
- 执行引擎在执行过程中执行的字节码指令依赖于pc寄存器
- 每当执行完一项,pc寄存器更新下一条指令
- 方法执行时,执行引擎可能通过存储在局部变量表中的对象引用定位到堆区的对应对象实例信息,以及通过对象头中的元数据指针定位到目标对象的类型信息(方法区)
java代码编译和执行的过程
如图,是大部分程序代码转换成物理机的目标代码或虚拟机能够执行得指令集之前都需要经历的步骤。
橙色部分是javac执行的操作(前端编译器)。
绿色部分是解释的过程,蓝色部分是编译的过程
java语言既有编译器,也有解释器(半解释,半编译):
- 解释器:当jvm启动时,会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容翻译为对应平台的本地机器指令执行。
- JIT编译器:jvm将源代码直接编译成与本地机器平台相关的机器语言。
机器码、指令、汇编语言
机器码
用二进制编码表示的指令,即机器指令码
虽然能被计算机理解和接受,但和人的语言差别过大,不易被理解和记忆。
用它编写的程序一经输入计算机,CPU直接读取运行,所以执行速度最快。
不同CPU,机器指令不同。
指令
由于机器码可读性太差,指令被发明了出来。
指令就是把机器码中特定的0-1序列,简化为对应指令,可读性稍好。
由于不同硬件平台,执行同一个操作,对应机器码不同,所以同一指令对应机器码也可能不同。
汇编语言
由于指令可读性太差,又发明了汇编语言
用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。
字节码
字节码是一种中间状态的二进制代码,比机器码更抽象,需要直译器转译后才能称为机器码。
字节码主要为了实现特定软件运行和软件环境,与硬件环境无关。(实现跨平台特点)
解释器分类
在Java的发展历史里,一共有两套解释执行器,即古老的字节码解释器、现在普遍使用的模板解释器。
字节码解释器在执行时通过纯软件代码模拟字节码的执行,效率非常低下。
而模板解释器将每一条字节码和一个模板函数相关联,模板函数中直接产生这条字节码执行时的机器码,从而很大程度上提高了解释器的性能。
在HotSpot VM中,解释器主要由Interpreter模块和Code模块构成。
- Interpreter模块:实现了解释器的核心功能
- Code模块:用于管理HotSpot VM在运行时生成的本地机器指令