深刻理解java:1.2. 字节码执行引擎

执行引擎是Java虚拟机的核心组成部分之一。java

 

首先,想一想C++和Java在编译和运行时到底有啥不同?jvm

下图左边,C++发布的就是机器指令,优化

而下图右边Java发布的是字节码,字节码在运行时经过JVM的类加载器,加载到JVM的虚拟内存的方法区,线程

再经过编译器、解释器作一次转换生成机器指令。执行引擎正是执行了这样的过程:输入的是内存中的字节码,处理过程是字节码解析的 等效过程,输出的是执行结果。对象

 

其次,再来看下图,JVM的内存结构:blog

 

 

1、执行方法。接口

每一个线程在建立后,都会产生一个程序计数器(pc)和栈(Stack)。内存

其中pc中存放了下一条将要执行的指令;ci

Stack中存放Stack Frame,存储了 当前正在执行的方法的信息,get

每一个方法的执行都会产生Stack Frame,Stack Frame中存放了   传递给方法的参数、方法内的局部变量以及操做数栈;

 

操做数栈用于存放指令运算的中间结果;

操做数栈在概念上很像CPU寄存器(CPU的内部元件:指令寄存器IR和程序计数器PC)。

java虚拟机没法使用寄存器,因此就用 操做数栈 来存放数据。

虚拟机把操做数栈做为它的工做区 —— 大多数指令都要从这里弹出数据,执行运算,而后把结果压回操做数栈。

好比,iadd指令就要从操做数栈中弹出两个整数,执行加法运算,其结果又压回到操做数栈中。

 

基于(操做数)栈的指令集 和基于寄存器的区别,

基于栈的指令集 是和硬件无关的,而基于寄存器则依赖于硬件基础。

基于寄存器在效率上优点。

可是虚拟机的出现,就是为了提供跨平台的支持,因此jvm的执行引擎是基于栈的指令集。

 

当方法执行完毕后则从Stack中弹出,继续其余方法的执行。

在继续执行方法时,JVM主要提供了invokestatic、invokevirtual、invokeinterface和invokespecial四种指令来执行。

 

在类加载的第二阶段--连接的第三阶段--解析,就肯定下来的,属于编译期可知,运行期不可变的方法:

(1) invokestatic:调用类的static方法,属于绑定类的调用

(2) invokespecial: 调用构造器,私有方法和父类方法,外部不可访问,绑定实例对象

还有一种是在运行时候解析的,只有在运行时才能肯定下来的,主要包含如下两方面:

(3) invokeinterface:调用接口方法,不肯定调用那一个实现类

(4) invokevirtual: 调用虚方法,不肯定调用哪个实现类 

 

2、执行技术

主要的执行技术有:解释,即时编译,自适应优化、芯片级直接执行

(1)解释:属于第一代JVM;

(2)即时编译:JIT属于第二代JVM;

(3)自适应优化:(目前Sun的HotspotJVM采用这种技术)吸收第一代JVM和第二代JVM的经验,采用二者结合的方式。

开始对全部的代码都采起解释执行的方式,

并监视代码执行状况,而后对那些 常常 调用的方法启动一个后台线程,将其编译为本地代码,并进行仔细优化。

若方法再也不频繁使用,则取消编译过的代码,仍对其进行解释执行;

(4)芯片级直接执行:内嵌在芯片上,用本地方法执行Java字节码。

相关文章
相关标签/搜索