jvm系列——3.执行引擎(建议按目录看)

JVM的执行引擎包括解释器和即时编译器JIT,解释器按行解释字节码,而JIT在运行时将字节码编译为本地机器码以提高性能。模板解释器通过预编译的指令集提高执行效率,而JIT通过热点探测和优化技术如方法内联、逃逸分析来进一步提升性能。HotSpotVM的ClientCompiler和ServerCompiler分别适用于启动速度和执行效率的优化,现代JVM常采用分层编译策略结合两者优势。
摘要由CSDN通过智能技术生成

S1.执行引擎(Execution Engine)介绍

JVM执行引擎是JVM的核心执行组件,负责将编译后的字节码解释成可执行的机器指令。扮演着将Java程序转换为机器指令的角色,实现了Java平台的跨平台特性。JVM执行引擎主要包括解释执行和即时编译两种方式,通过解释器执行字节码文件时,性能低,但具有跨平台的优势;而即时编译技术可以将频繁执行的代码优化为本地机器码,提高执行效率。执行引擎主要包括了解释器(Interpreter),即使编译器JIT(Just In Time Compiler)和垃圾收集器(Garbage Collection)。本文只探讨解释器和JIT的含义,垃圾收集器在接卸来的单独章节进行讲解。

S2.解释器(Interpreter)

当 JVM启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容“翻译”为对应平台的本地机器指令执行。

S2.1.字节码解释器

字节码解释器是早期出现的解释器,在执行时,通过纯软件代码模拟字节码的执行,效率非常低下。

S2.2.模板解释器

模板解释器是现在普遍使用解释器,是一种优化技术,它的主要作用是将Java字节码转换为一个比解释执行更快的执行方式。 使用模板解释器的JVM会将常见的字节码序列预先编译成一组高效的机器码指令集,这些指令集被组织成一个类似于函数的结构,成为模板。当JVM在运行Java程序时,它会根据当前执行的方法和字节码,选择一个最匹配的模板来执行,并且能够在最短的时间内完成。模板解释器的执行速度会比纯解释执行快,因为它可以利用已经编译好的指令集,避免每次执行指令时的解析和翻译操作,从而减少了执行时间。模板解释器还可以更好地优化处理长时间运行的循环和条件语句,提高程序的执行效率。

S3.即时编译器JIT(Just In Time Compiler)

虽然,使用模板解释器会带来更快的执行速度和更高的程序性能。但是由于解释器在设计和实现上非常简单,无论是哪种解释器都拜托不了低效的标签。所以java引入了即时编译技术,诞生了即时编译器JIT。

JVM 的即时编译器是一种十分重要的优化技术,它的主要作用是将 Java 字节码在运行时即时编译成本地机器码,以提高 Java 代码的执行效率和性能。众所周知,解释执行的方式效率比编译执行要慢很多。在这种情况下,即时编译器就可以派上用场了。它可以实时地对 Java 字节码进行编译,将其转换成本地机器码,这样一来,在以后的执行过程中,就不需要再解释执行了,直接执行本地机器码即可,因此执行效率也会得到显著提高。除了提高执行效率之外,即时编译器还可以利用 运行时分析 信息来对代码进行优化,比如在热点代码段中进行方法内联或循环展开,以进一步提高代码的执行效率。

目前大多数执行引擎采用解释器与即时编译器并存的架构,解释器和即时编译器相互协作,各自取长补短,选择最合适的方式来权衡编译本地代码的时间和直接解释执行代码的时间。

以HotSpot VM为例默认的程序执行方式:

在虚拟机启动的时候,解释器可以首先发挥作用,而不必等待即时编译器全部编译完成再执行,在启动时省去许多不必要的编译时间。

随程序运行时间推移,即时编译器逐渐发挥作用,根据热点探测功能,将满足触发JIT条件的字节码编译为本地机器指令,以换取更高的程序执行效率。

S3.1.JIT分类(以HotSpot VM为例的)

HotSpot VM中有两种JIT,Client Compiler和Server Compiler。

Client Compiler主要优化策略有方法内联,去虚拟化、冗余消除。

方法内联:方法内调用方法时,将引用的函数代码编译到引用点处,这样可以减少栈帧的生成,减少参数传递以及跳转过程;

去虚拟化:对唯一的实现类进行内联;

冗余消除:在运行期间把一些不会执行的代码折叠掉。

Server Compiler主要优化是在全局层面,逃逸分析是优化的基础。通过 逃逸分析有如下优化:(server模式下才会有这些优化,64位系统默认就是server模式)

标量替换:用标量值代替聚合对象的属性值;

栈上分配:对于未逃逸的对象分配对象在栈而不是堆;

同步消除:清除同步操作,通常指synchronized锁 。

Server Compiler编译器启动时长比Client Compiler编译器慢,系统稳定执行以后,Server Compiler编译器执行速度远远快于Client Compiler编译器;

JDK1.8开始,如在程序中显式指定命令"-server"时,默认将会开启分层编译策略,由Client Compiler编译器和Server Compiler编译器相互协作共同来执行编译任务。

逃逸分析:判断对象是否被外部引用所及,及对象的生命周期以及作用域等信息。根据逃逸分析的结果,JIT编译器可以进行一些优化,例如栈上分配对象、锁消除、方法内联等优化措施,从而提升程序的性能和效率。逃逸分析主要的目的是节省内存和提高程序的执行效率。

S3.3.热点探测

热点探测技术是JIT编译器优化的关键之一,它可以通过监测程序的运行时间、方法调用次数等指标,识别出程序中频繁执行的代码块(即“热点代码”),判断是否需要启动JIT编译器将字节码直接编译为对应平台的本地机器指令。

HotSpot VM目前采用的热点探测方式是基于计数器的热点探测。为每个方法建立2个不同类型的计数器:方法调用计数器(Invocation Counter) 和回边计数器(Back Edge Counter) 。方法调用计数器,用于统计方法的调用次数;回边计数器,用于统计循环体执行的循环次数。通过计算方法调用计数器与回边计数器值之和是否超过方法调用计数器的阈值。如果已超过阈值,将会向即时编译器提交一个该方法代码编译请求。

方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即一段时间之内方法被调用的次数。当超过一定的时间限度, 方法的调用次数不足以让它提交给即时编译器编译,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减(Counter Decay) ,而这段时间就称为此方法统计的半衰周期(Counter Half Life Time)。进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

商贸的赵老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值