引擎源码怎么编译-JVM-第10章-执行引擎

JVM——执行引擎

1 概述

执行引擎是Java虚拟机的核心组件之一。

虚拟机”是一个相对于“物理机”的概念。 两台机器都具有代码执行能力。 不同的是,物理机的执行引擎直接构建在处理器、缓存、指令集、操作系统层面。 ,而虚拟机的执行引擎是由软件本身实现的,因此指令集和执行引擎的结构可以不受化学条件的阻碍而进行定制,并且可以将这些硬件不直接支持的指令集格式被执行。

JVM的主要任务是将字节码加载到其内部,但是字节码不能直接在操作系统上运行,因为字节码指令并不等同于本地机器指令,它只包含一些能力。 字节码指令、符号表以及JVM识别的其他辅助信息。

那么,如果要运行Java程序,执行引擎(Execution Engine)的任务就是将字节码指令解释/编译成相应平台上的本地机器指令。 简单来说,JVM中的执行引擎充当从高级语言到机器语言的翻译器。

执行引擎工作流程

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

2、Java代码的编译和执行过程

大部分程序代码在转换成物理机的目标代码或者虚拟机可以执行的指令集之前,需要经过右图中的各个步骤。

Java是一种半编译、半解释的语言,红色部分是半编译,红色部分是半解释:

Java代码编译是由Java源代码编译器(前端编译器)完成的,流程图如下:

Java字节码的执行是由JVM执行引擎(后端编译器)完成的,流程图如下:

问题:什么是协程(解释器)以及什么是 JIT 编译器?

问:为什么说Java是半编译半解释型语言?

3.机器代码、指令、汇编语言机器代码指令指令集汇编语言高级语言

字节码

Java文件编译出来的字节码文件需要再次编译或者解释汇编制成机器指令。

字节码文件的主要目的是实现跨平台引擎源码怎么编译,而执行引擎则是专门处理字节码文件的。

4. 口译员

JVM设计者的初衷很简单,就是为了满足Java程序的跨平台特性,因此杜绝采用高级语言形式的静态编译直接生成本地机器指令,从而催生了协程的实现在运行时使用字节的逐行解释。 代码执行程序视图。

口译员分类

在Java的发展历史中,有两套解释执行器,即古老的字节码类库和现在常用的模板类库。

现状

因为协程的设计和实现都非常简单,所以不仅是Java语言,很多高级语言也是基于原语来执行的,比如Python、Perl、Ruby等。但是今天,基于原语的执行已经长期以来一直是低效率的代名词,并且经常被一些C/C++程序员嘲笑。

为了解决这个问题,JVM平台支持一种称为即时编译的技术。 即时编译的目的是为了防止函数被解释执行,而是将整个函数体编译为机器代码。 每次执行该函数时,仅执行编译后的机器代码。 这种方法可以大大提高执行效率。

引擎源码怎么编译-JVM-第10章-执行引擎

无论如何,基于原语的执行模式始终为中间语言的发展做出了不可磨灭的贡献。

5、JIT编译器Java代码的执行分类问题来了

有的开发者会感到奇怪,既然HotSpot VM已经有了外部JIT编译器,为什么还需要使用协程来“拖累”程序的执行性能呢? 例如,JRockit VM不包含类库,所有字节码都是在即时编译器的帮助下编译和执行的。

首先明确:

当程序启动时,解释器可以立即生效,节省编译时间并立即执行。

为了让编译器发挥作用,需要一定的执行时间才能将代码编译为本机代码。 不过编译成本机代码后,执行效率很高。

所以:

虽然程序在JRockit VM中的执行性能会非常高效,但是程序在启动时不可避免地需要更长的编译时间。 对于服务器端应用程序来说,启动时间不是重点,但对于这些启动时间很重要的应用场景,可能需要采用原语和即时编译器共存的架构,以换取一个平衡点。 在这种模式下,当Java虚拟机启动时,解释器可以先生效,无需等待即时编译器完成编译后再执行,这样可以节省很多不必要的编译时间。 随着时间的推移,编译器开始发挥作用,将越来越多的代码编译为本机代码,以提高执行效率。

同时,当编译器不进行激进的优化时,解释执行被用作编译器的“逃生门”。

HotSpot JVM执行方法

当虚拟机启动时,解释器可以先生效,无需等待即时编译器编译后再执行,这样可以节省很多不必要的编译时间。 并且随着程序运行时间的推移,即时编译器会逐渐发挥作用,根据热点检测功能将有价值的字节码编译为本地机器指令,以换取更高的程序执行效率。

概念解释

Java语言的“编译期”实际上是一个“不确定”的操作过程,因为它可能指的是后端编译器(实际上叫“编译器后端”更准确)将.java文件转换为.class文件编制过程;

也可能指虚拟机前端运行时编译器(JIT编译器,Just In Time Compiler)将字节码转换为机器码的过程。

也可能指直接编译的过程。 使用静态早期编译器(AOT 编译器,Ahead of Time Compiler)将 java 文件转换为本地机器代码。

热点代码及检测方法

当然,是否需要启动JIT编译器直接将字节码编译成对应平台的本地机器指令,取决于代码被调用和执行的频率。 对于这些需要编译为本机代码的字节码,也称为“热代码”。 JIT编译器会对这些运行时经常被称为“热代码”的代码进行深度优化,将其直接编译成对应平台的本地机器指令,从而提高Java程序的执行性能。

方法调用计数器

热衰后缘计数器

它的作用是统计某种模式下循环体代码被执行的次数,字节码中遇到控制流后跳转的指令称为“Back Edge”。 显然引擎源码怎么编译,设置back-to-edge计数器统计的目的是为了触发OSR编译。

HotSpotVM可以设置程序执行模式

默认情况下,HotSpot VM 采用原语和即时编译器共存的框架。 当然,开发者可以根据具体的应用场景,通过命令明确指定Java虚拟机在运行时是使用原语还是即时编译器。 完全使用即时编译器执行。 如下:

HotSpotVM 中的 JIT 分类

HotSpot VM 中嵌入了两种 JIT 编译器,分别是 Client Compiler 和 Server Compiler,但大多数情况下我们简称为 C1 编译器和 C2 编译器。 开发者可以通过以下命令显式指定Java虚拟机在运行时使用哪种即时编译器,如下:

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

但Java7版本之后,一旦开发者在程序中显式指定命令“-server”,就会默认启用分层编译策略,C1编译器和C2编译器会相互配合执行编译任务。

C1和C2编译器的不同优化策略

在不同的编译器上有不同的优化策略;

C1编译器主要有内联、去虚拟化、冗余去除等方法:

C2的优化主要是在全局层面,逃逸分析(前面提到过,还不成熟)是优化的基础。 基于逃逸分析,C2有以下优化:

JIT总结

参考尚硅谷宋宏康的全套JVM教程(详细java虚拟机)

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 引擎源码怎么编译-JVM-第10章-执行引擎 https://www.wkzy.net/game/174694.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务