JVM能够跨计算机体系结构来执行Java字节码,主要是由于JVM屏蔽了与各个计算机平台相关的软件或者是硬件之间的差异,使得与平台相关的耦合统一由JVM提供者来实现。
何为JVM
JVM的全名是Java Virtual Machine(Java虚拟机)。它是通过模拟一个计算机的形式来实现到计算机所具有的计算功能。让我们先来看看一台真实的计算机具备计算功能的条件:
指令集 | 这个计算机所能识别的机器语言的命令集合。 |
计算单元 |
即能够识别并且控制指令执行的功能模块
|
寻址方式
|
地址的位数、最小地址和最大地址范围,以及地址的运行规则 |
寄存器定义
|
包括操作数寄存器、变址寄存器、控制寄存器等的定义、数量和使用方法
|
存储单元
|
能够存储操作数和保存操作结构的单元,如内核级缓存、内存和磁盘等
|
指令集:所谓指令集就是在CPU中用来计算和控制计算机系统的一套指令的集合,每种CPU在设计的时候就已经规定了一套与硬件电路想配合的指令系统。指令集的先进与否是体现CPU性能 的一个重要指标。
在当前的计算机中有哪些指令集?从主流的体系结构分为RISC(Reduced Instruction Set Computing,精简指令集)和
CISC(Complex Instruction Set Computing,复杂指令集)。当前我们普遍使用的桌面操作系统中基本是用CISC。除了这两种指令外,一些公司如Intel和AMD等CPU厂家还在它们的基础上进行了一些扩展指令集。
指令集和汇编语言有什么关系?指令集是可以直接被机器识别的机器码,也就是说它必须以二进制格式存在于计算机中。而汇编语言则是能够被人识别的指令,汇编语言在顺序和逻辑上是与机器指令一一对应的。换句话说,就是汇编语言是为了让人能够更容易记住机器指令而使用的助记符。
指令集与CPU架构有何联系?汇编语言都是对寄存器和段进行直接操作的命令。这些寄存器和段等芯片都是架构的一部分,因此不同的芯片架构设计一定会对应到不同架构的指令集。但是由于迫于操作系统局限的缘故(操作系统是管理计算机的真正入口,几乎所有的程序都要经过操作系统来调用),所以基本上不同的芯片厂商都会研发采用兼容的方式来兼容不同架构的指令集。
JVM和实体机一样有一套合适的指令集,这个指令集能够被JVM解析执行,这个指令集我们称为JVM字节码指令集,符合class文件规范的字节码都可以被JVM执行
扯了那么多,还是回到JVM的话题上来吧,JVM和实体机的不同主要有三大点:
一个抽象规范
|
这个规范约束了JVM是什么,有哪些组成部分等等。
|
一个具体实现
|
所谓具体的实现是不同的厂商按照这个抽象的规范用软件或者软硬结合在相同或不同的平台上的具体实现。
|
一个运行的实例
|
当用JVM运行一个Java实例时,它就是一个运行中的实例,每个运行中的Java程序都是一个JVM实例 |
JVM体系结构分析
结构基本上由四部分组成:
类加载器
|
在JVM启动时或者是在类运行时将需要的class文件加载到JVM中 |
执行引擎
|
负责执行class文件中包含的字节码指令,相当于实际机器上的CPU |
内存区
|
将内存划分为若干个区以模拟实际机器上的存储、记录和调度功能模块 |
本地方法调用
|
调用C或C++实现的本地方法的代码返回结果 |
类加载器:每个被JVM装载的类型都有一个对应的java.lang.Class类的实例来表示该类型,该类型可以唯一的表示被JVM装载的class类,要求这个实例和其他类的实例一样都存放在Java的堆中。
执行引擎:核心部分。执行引擎的作用就是解析JVM字节码指令,得到执行结果。在《Java虚拟机规范》中详细地定义了执行引擎遇到每条字节码指令时应该处理什么,并且应该得到什么结果。但是没有规定执行引擎应该如何过采取什么方式处理而得到这个结果。不同的厂商有自己不同的实现方式。
执行引擎也就是执行一条条代码的一个流程,而代码都是包含在方法体内的,所以执行引擎本质上就是执行一个个方法所串起来的流程。对应到操作系统中一个执行流程就是一个Java线程。因为一个Java进程可以有多个同时执行的执行流程。所以每个Java线程就是一个执行引擎的实例。
Java内存管理:执行引擎在执行一段程序时需要存储一些东西(如操作数、执行结果等)。class类的字节码还有类的对象等信息都需要在执行引擎执行之前就准备好。由上图可知一个JVM实例会有一个方法区、Java堆、Java栈、PC寄存器和本地方法区。其中方法区和Java堆是所有线程共享的,也就是说可以被所有的执行引擎实例访问。每个新的执行引擎实例被创建时会为这个执行引擎创建一个Java栈和一个PC寄存器,如果当前正在执行一个Java方法,那么当前的这个Java栈中保存的是该线程中方法调用的状态,包括方法的参数、方法的局部变量、方法的返回值以及运算的中间结果等。而PC寄存器会指向即将执行的下一条指令。