十二-执行引擎

12.1 执行引擎概述

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

JVM主要任务是负责装载字节码到其内部,如果想要一个Java程序运行起来,执行引擎(Execution Engine)的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以。

JVM
执行引擎的工作过程

过程
从外观上来看,所有Java虚拟机的执行引擎输入、输出都是一致的。输入时字节码二进制流,处理过程时字节码解析执行的等效过程,输出的是执行结果。

12.2 代码编译和执行过程

大部分的程序代码转换成物理机的目标代码或虚拟机能执行的指令集之前,都需要经过以下步骤

编译和执行
解释器和编译器

解释器和编译器

什么是解释器(Interpreter),什么是JIT编译器

  • 解释器:当Java虚拟机启动时会根据预定义的规范堆字节码采用逐行解释的方式执行,将每条字节码文件中的内容“翻译"为对应平台的本地机器指令执行
  • JIT(Just In Time Compiler)编译器:虚拟机将源代码直接编译成和本地机器平台相关的机器语言

12.3 机器码、指令、汇编语言

机器码
各种用二进制编码方式表示的指令,叫做机器指令码
机器指令与CPU紧密相关,所以不同种类的CPU对应的机器指令不同

指令
机器码只有0和1组成,人们发明了指令
指令就是把机器码简化成对应的指令,可读性好

指令集

不同的硬件平台,各自支持的指令是有差别的。因此每个平台所支持的指令,称之为对应平台的指令集。
X86指令集
ARM指令集

汇编语言

汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或符号(Label)代替指令或操作数的地址

高级语言

高级语言
字节码

一种中间状态(中间码)的二进制代码(文件),比机器码更抽象,需要直译器转译后才能成为机器码

12.4 解释器

解释器
JVM设计者的初衷仅仅只是单纯地为了满足Java程序实现跨平台特性,因此避免采用静态编译的方式直接生成本地机器指令,从而诞生了实现解释器在运行时采用逐行解释字节码执行程序的想法

解析器所承担的角色就是一个运行时”翻译者“,将字节码”翻译“为对应平台的本地机器指令执行

分类:
古老的字节码解释器、现在普遍使用的模板解释器
在HotSpot中,解释器主要由IInterpreter模块和Code模块构成

由于解释器设计实现上非常简单,基于解释器执行已经沦为低效的代名词,为解决这个问题,JVM支持了一种即时编译的技术。将整个函数体编译成为机器码,每次函数执行时,只执行编译后的机器码即可。

12.5 JIT编译器

Java代码的执行分类
第一种是将源代码编译成字节码文件,然后在运行时通过解释器将字节码文件转为机器码执行
第二种是编译执行,直接翻译成机器码,会使用即时编译技术(JIT,Just In Time)将方法编译成机器码后再执行

HotSpot JVM的执行方式
当虚拟机启动时,解释器首先发挥作用,不必等待即时编译器全部编译完成后再执行,可以省去不必要的编译时间,随着程序运行时间的推移,即时编译器根据热点探测功能,将有价值的字节码编译为本地机器指令。

Java的”编译期“是一段”不确定“的操作过程,因为他可能是指一个前端编译器把.java转变成.class文件的过程
也可能是虚拟机的后端运行期编译器(JIT)把字节码转变为机器码的过程
也可能是指使用静态提前编译器(AOT,Ahead of Time Compiler)直接把.java编译成本地机器代码的过程

前端编译器:Sun的Javac,Eclipse JDT中的增量式编译器(ECJ)
JIT编译器:HotSpot的C1\C2编译器
AOT编译器:GNU Compiler for the Java(GCJ)\Excelsior JET

热点代码

一个被多次调用的方法,或者是一个方法体内部循环次数较多的循环体都可以被称为”热点代码“,都可以通过JIT编译器编译为本地机器指令,也被称之为栈上替换,OSR(On Stack Replacement)编译

目前HotSpot VM采用的热点探测方式是基于计数器的热点探测

采用基于计数器的热点探测,方法调用计数器(Invocation Counter),。和回边计数器(BackEdge Counter)

方法调用计数器

用于统计方法的调用次数,默认阈值在Client模式下是1500次,在Server模式下是10000次,超过阈值,就会触发JIT编译,可以通过-XX:CompileThreshold设定
方法调用计数器

回边计数器

用于统计循环体执行的循环次数,在字节码中遇到控制流向后跳转的指令称为”回边“(Back Edge),建立回边计数器统计的目的就是为了触发OSR编译

回边

-Xint:完全采用解析器模式执行;
-Xcomp:完全采用即时编译器模式执行程序。如果即时编译出现问题,解释器会介入
-Xmixed:采用混合模式共同执行

模式
HotSpot VM中JIT分类

JIT有两个编译器,分别为Client Compiler和Server Compiler,简称C1和C2
-clinet:指定Java虚拟机Client模式,使用C1编译器,对字节码进行简单和可靠的优化,耗时短,以达到更快的编译速度
-server:指定Java虚拟机运行在Server模式下,使用C2编译器,进行耗时较长的优化,以及激进优化。但优化的代码执行效率更高(使用C++)

C1和C2不同的优化策略
C1主要有方法内联,去虚拟化,冗余消除
C2主要在全局层面,逃逸分析是优化的基础。标量替换,栈上分配,同步消除

分层编译(Tiered Compilation)策略
程序解释执行(不开启性能监控)可以触发C1编译,将字节码编译成机器码,可以进行简单优化,也可以加上性能监控,C2编译会根据性能监控信息进行激进优化

JDK10后

  • JDK10起,加入一个全新的即时编译器:Graal编译器,需要使用-XX:+UnlockExperimentalVMOptions -XX:+UserJVMCICompiler去打开
  • JDK9引入了实验性AOT编译工具jaotc,借助了Graal编译器,将所输入的Java类文件转换为机器码,并存放到生成的动态共享库中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值