执行引擎
2021-09-18 16:32:36 0 举报
执行引擎
作者其他创作
大纲/内容
指令流
动态链接
栈 帧 1
一个被多次调用的方法,或者是一个方法体内部循环次数较多的循环体都可以被称之为“热点代码”,因此都可以通过JIT编译器编译为本地机器指令。由于这种编译方式发生在方法的执行过程中,因此也被称之为栈上替换 一个方法究竟要被调用多少次,或者一个循环体究竟需要执行多少次循环才可以达到这个标准?必然需要一个明确的阈值,JIT编译器才会将这些“热点代码”编译为本地机器指令执行。这里主要依靠热点探测功能。 ·目前HotSpot VM所采用的热点探测方式是基于计数器的热点探测。 ·采用基于计数器的热点探测,HotSpot VM将会为每一个方法都建立2个不同类型的计数器,分别为方法调用计数器(Invocation Counter)和回边计数器(BackEdge cCounter) 。 >方法调用计数器用于统计方法的调用次数,client模式下,阈值是1500,server模式下阈值是10000,超过这个阈值,就会触发JIT。 >回边计数器则用于统计循环体执行的循环次数
即时编译结束
热点代码
到对象类型的指针
方法调用计数器执行流程
执行编译后的本地代码版本
词法分析
执 行 流 程
Java方法返回
JIT分类
向编译器提交OSR编译请求
Java源代码
是否超过阈值
Java代码编译和执行的过程
N
局部变量表
栈 帧 n
Y
执 行 引 擎
遇到回边指令
程序源码
它的作用是统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为“回边”(Back Edge)。显然,建立回边计数器统计的目的就是为了触发oSR编译。
回边计数器执行流程
后台编译执行
JIT编译器
执行引擎执行的过程中执行什么样的指令完全依赖于PC寄存器。 当一个指令被执行后,PC寄存器就会更新下一个需要执行的指令地址。 当方法执行过程中,执行引擎通过局部变量表中的方法引用定位到Java堆中的对象实例,通过对象头信息中的类型指针定位到方法区的该对象所属的实际类型。
当程序启动时,当Java虚拟机启动的时候会根据预定义的规范对字节码逐行解释的方式进行,将每行字节码文件中的内容\"翻译\"成对应平台的机器语言指令。为了满足Java程序跨平台的特性,因此避免采用静态编译的方式直接生成机器指令,从而诞生了解释器在运行时逐行解释字节码执行程序的想法。
操作数栈
方法区
栈 帧 2
方法返回地址
语法分析
执行编译后的机器码
解释器
Code Cache
中间代码
探测方式
执行引擎
PC寄存器
单次流
回边计数器+1
类型信息
Java堆区
以解释方式继续执行
优化器(可选)
对象实例
调整回边计数器值
JIT编译器:虚拟机将源代码编译成本地机器平台相关的机器语言。当程序启动时,解释器可以首先发挥作用,而不必等待即时编译器全部编译后执行,这样可以省去很多不必要的编译时间。随着时间的推移,把越来越多的代码编译成本地代码提高执行效率。 编译器分类: · 前端编译器,把.java文件编译成.class文件的过程 · 后端运行期编译器,把 字节码转换成机器码的过程。 · 静态提前编译器,直接把.java文件编译成机器码的过程。
生成器
两计数器之后是否超过阈值
解释执行
是否编译
编译器、解释器
方法返回
编译器
抽象语法树
目标代码
.-client:指定Java虚拟机运行在client模式下,并使用c1编译器; c1编译器会对字节码进行简单和可靠的优化,耗时短。以达到更快的编译速度。.-server:指定Java虚拟机运行在server模式下,并使用c2编译器。 C2进行耗时较长的优化,以及激进优化。但优化的代码执行效率更高。 C1和C2编译器不同的优化策略∶ ·在不同的编译器上有不同的优化策略,c1编译器上主要有方法内联,去虚拟化、冗余消除。 方法内联:将引用的函数代码编译到引用点处,这样可以减少栈帧的生成,减少参数传递以及跳转过程 >去虚拟化:对唯一的实现类进行内联 >冗余消除:在运行期间把一些不会执行的代码折叠掉 C2的优化主要是在全局层面,逃逸分析是优化的基础。基于逃逸分析在c2上有如下几种优化:>标量替换:用标量值代替聚合对象的属性值 >栈上分配:对于未逃逸的对象分配对象在栈而不是堆>同步消除:清除同步操作,通常指synchronized
解释方式执行
是否存在以编译版本
方法调用计数器+1
执行引擎是Java虚拟机的重要组成部分。 执行引擎是相对于\"物理机\"的概念,它们都有执行代码的能力,但是物理机的执行引擎是基于处理器、缓存、指令集和操作系统层面上的,而Java中的执行引擎则是由软件自行实现的,因此,它不必受到物理条件制约的制定指令集与执行引擎的结构体系,可以执行那些不被硬件直接支持的指令集格式。 JVM的作用是负责将字节码装载到其内部,但字节码并不能直接运行在操作系统之上,因为字节码并不等价于机器语言,它内部包含的仅仅是一些能被JVM识别的字节码指令、符号表,以及其他符号信息。执行引擎的作用就是将字节码指令编译/解释成对应平台的本地机器指令才可以是Java程序运行。
概述
当前栈
提交编译请求
......
半衰周期
当然是否需要启动JIT编译器将字节码直接编译为对应平台的本地机器指令,则需要根据代码被调用执行的频率而定。关于那些需要被编译为本地代码的字节码,也被称之为“热点代码”,JIT编译器在运行时会针对那些频繁被调用的“热点代码”做出深度优化,将其直接编译为对应平台的本地机器指令,以此提升Java程序的执行性能。
0 条评论
下一页