JVM 执行引擎

news2024/11/30 0:37:23

执行引擎概述

  • 是Java 虚拟机核心的组成部分之一
  • 物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行哪些不被硬件直接支持的指令集格式
  • JVM 主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被 JVM 所识别的字节码指令、符号表,以及其他辅助信息
  • 想让一个 Java 程序运行起来,执行引擎(Execution Engine) 的任务就是将字节码指令解释 / 编译为对应平台上的本地机器指令才可以。简单来说, JVM 中的执行引擎充当了将高级语言翻译为机器语言的译者 

执行引擎的工作过程:

  • 执行引擎在执行的过程中究竟需要执行什么样的字节码指令完全依赖于 PC 寄存器
  • 每当执行一项指令操作后,PC寄存器就会更新下一条需要被执行的指令地址
  • 当前方法在执行的过程中,执行引擎有可能会通过存储在局部变量表中的对象引用准确定位到存储在Java 堆区中的对象实例信息,以及通过对象头重的元数据指针定位到目标对象的类型信息
  • 所有的Java 虚拟机的执行引擎输入、输出都是一致的;输入的字节码二进制流,处理过程是字节码解析执行的等效过程,输出的执行结果

Java 代码编译和执行过程

Java 字节码的执行是由 JVM 执行引擎来完成,流程图如下:

 解释器: 当 Java 虚拟机穷的那个时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容 "翻译"为对应平台的本地机器指令执行

JIT(Just In Time Compiler) 即时编译器: 就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言

解释器

  • JVM 设计者们的初衷仅仅只是单纯地为了满足 Java 程序实现跨平台特性,因此避免采用静态编译的方式直接生成本地机器指令,从而诞生了实现解释器在运行时采用逐行解释字节码执行程序的想法
  • 所承担的角色就是一个运行时"翻译者",将字节码文件中的内容"翻译"为对应平台的本地机器指令执行
  • 当一条字节码指令被解释执行完成后,接着再根据 PC 寄存器中记录的下一条需要被执行的字节码指令执行解释操作

JIT 编译器

HotSpot VM 是目前市面上的高性能虚拟机的代表之一,采用解释器和及时编译期并存架构。在Java 虚拟机运行时,解释器和即时编译器能够相互写作,取长补短,尽力去选择最合适的方式来权衡编译本地代码的时间和直接解释执行代码的时间

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

编译器分类:

  • 前端编译器: 将 .java 文件转变成 .class 文件的过程
  • 后端运行期编译器: 把字节码转变成机器码的过程, C1、C2 
  • 静态提前编译器: 直接把 .java 文件编译成本地机器代码的过程

热点代码和探测方式:

  • 当然是否需要启动 JIT 编译器将字节码直接编译为对应平台的本地机器指令,则需要根据代码被调用执行的频率而定。关于那些需要被编译为本地代码的字节码,也被称为"热点代码",JIT 编译器在运行时会针对那些频率被调用的"热点代码"做出深度优化,将其直接编译为平台的本地机器指令,以提升 Java 程序的执行性能
  • 一个被多次调用的方法,或者是一个方法体内部循环次数较多的循环都可以被称为"热点代码",因此都可以通过 JIT 编译器编译为本地机器指令。由于这种编译方式发生在方法执行的过程中,因此也被称之为栈上替换,或简称为 OSR(On Stack Replacement) 编译
  • JIT 编译器将这些"热点代码"编译为本地机器指令执行。主要依靠热点探测功能,即基于计数器的热点探测。HotSpot VM 将会为每一个方法都建立2个不同类型的计数器,分别是调用计数器(Invocation Counter) 和回边计数器(Back Edge Counter)。方法调用计数器用于统计方法的调用次数,回边计数器则用于统计循环体执行的循环次数

方法调用计数器:

  • 用于统计方法被调用的次数,它的默认阈值在 client 模式下是 1500次,在 Server 模式下 10000次。超过这个阈值,就会触发 JIT 编译
  • 这个阈值可以哦他能够过虚拟机参数 -XX: CompileThreshold 来人为设定
  • 当一个方法被调用时,会先检查该方法是否存在被 JIT 编译过的版本,如果存在,则优先使用编译后的本地代码来执行。如果不存在已被编译过的版本,则将此方法的调用计数器加 1,  然后判断方法调用计数器与回边计数器值之和是否超过方法调用计数器的阈值。如果已超过阈值,那么将会向即使编译器提交一个该方法的代码编译请求

 

热度衰减:

  • 如果不做任何设置,方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即一段时间之内方法被调用的次数。当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即使编译器,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减(Counter Decay),而这段时间就称为此方法统计的半衰周期(Counter Half Life Time)
  • 进行热度衰减的动作是虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数 -XX:-UseCounterDecay 来关闭热度衰减,让方法计数器统计方法调用的绝对次数,这样,只要系统运行时间足够长,绝大部分方法都会被编译成本地代码
  • 使用 -XX:CounterHalfLifeTime 参数设置半衰周期的时间,单位是秒

回边计数器:

它的作用是统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向跳转的指令称为"回边(Back Edge)"。 显然,建立回边计数器统计的目的就是触发 OSR 编译

VM 设置程序执行方式:

  • -Xint: 完全采用解释器模式执行程序
  • -Xcomp: 完全采用即使编译器模式执行程序。如果即使编译器出现问题,解释器会介入执行
  • -Xmixed: 采用解释器 + 即使编译器的混合模式共同执行程序
/**
 * 设置执行模式 查看耗时
 */
public class IntCompTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        testPrimeNumber(1000000);
        long end = System.currentTimeMillis();
        System.out.println("花费时间为:" + (end - start));
    }

    private static void testPrimeNumber(int count) {
        for (int i = 0; i < count; i++){
            label: for (int j = 2; j<= 100; j++) {
                for (int k = 2; k <= Math.sqrt(j); k++){
                    if (j % k ==0) {
                        continue label;
                    }
                }
            }
        }
    }
}

VM 的 JIT 分类:

  • 在 HotSpot VM 中内嵌有两个 JIT 编译器,分别为 Client Compiler 和 Server Compiler,但大多数情况下简称 C1 编译器和C2 编译器
  • -client: 指定 Java 虚拟机运行在 Client 模式下,并使用 C1 编译器; C1 编译器会对字节码进行简单和可靠的优化,耗时短。以达到更快的编译速度
  • -server: 指定 Java 虚拟机运行在 Server 模式下,并使用 C2 编译器。 C2 编译器耗时较长的优化以及激进优化。但优化的代码执行效率更高

C1 的优化策略:

  • 方法内联: 将引用的函数代码编译到引用点处,这样可以减少栈帧的生成,减少参数传递以及跳转过程
  • 去虚拟化: 对唯一的实现类进行内联
  • 冗余消除: 在运行期间把一些不会执行的代码折叠掉

C2 的优化策略: 在全局层面,逃逸分析是优化的基础

  • 标量替换: 用标量值代替聚合对象的属性值
  • 栈上分配: 对于未逃逸的对象分配在栈而不是堆
  • 同步消除: 消除同步操作,通常指 synchronized

分层编译(Tiered Comlilation) 策略:

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

AOT 编译器:

  • jdk9引入 AOT 编译器(静态提前编译器, Ahead Of Time Compiler)
  • Java 9 引入了实验性 AOT 编译工具 jaotc。它借助了 Graal 编译器,将所有输入的 Java 类文件转换为机器码,并存放至生成的动态共享库之中
  • AOT 编译指,在程序运行之前,将字节码转换为机器码的过程

AOT缺点:

  • 破坏了java"一次编译,到处运行",必须为每个不同硬件、OS编译对象的发行包
  • 降低了 Java 链接过程的动态性,加载的代码在编译期就必须全部已知
  • 还需要继续优化,最初只支持 linux 64 java base

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/528061.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2、Flume进阶

目录 1、Flume事务 1.1 Flume事务 1.2 Flume Agent内部原理 1.3 重要组件&#xff1a; 2、 Flume拓扑结构 2.1 简单串联 2.2 复制和多路复用 2.3 负载均衡和故障转移 2.4 聚合 3、开发案例 3.1 复制和多路复用 3.4.2 负载均衡和故障转移 3.3 聚合 1、Flume事务 1.…

在数据化知识经济的时代,你该学会如何经营好自己的知识管理

在当今的数据化知识经济时代&#xff0c;知识管理已经越来越成为了一个必备的技能。在这个竞争激烈的时代&#xff0c;拥有良好的知识管理能力&#xff0c;可以帮助我们更好地应对各种挑战和机遇。 如何经营好自己的知识管理 一、认识知识管理的重要性 知识管理是指通过系统…

【计算机视觉】如何利用 CLIP 做简单的图像分类任务?(含源代码)

要使用 CLIP 模型进行预测&#xff0c;您可以按照以下步骤进行操作&#xff1a; 一、安装 安装依赖&#xff1a;首先&#xff0c;您需要安装相应的依赖项。您可以使用 Python 包管理器&#xff08;如 pip &#xff09;安装 OpenAI 的 CLIP 库。 pip install githttps://gith…

2023年Android开发者路线-第1部分

2023年Android开发者路线-第1部分 2023年Android开发者路线-第2部分 2023年Android开发者路线-第3部分 2023年Android开发者路线-第4部分 2023年Android开发者路线-第1部分 Android 生态系统处于不断发展的状态&#xff1a;每天都会引入新的库和资料&#xff0c;旨在加快开…

linux常见指令以及权限理解

1.linux下基本指令&#xff1a; ls指令&#xff1a; 查看文件的属性 ls-l&#xff1a;文件的属性 ls-la:显示所有文件的属性 ls *&#xff1a; linux任何一个目录下面都有两个隐藏文件&#xff1a; ..&#xff1a;表示当前路径的上级路径&#xff0c;可以原路返回 .&…

分布式锁-01(单节点解决方案)

分布式锁概述 为什么需要分布式锁 在单机部署的系统中&#xff0c;使用线程锁来解决高并发的问题&#xff0c;多线程访问共享变量的问题达到数据一致性&#xff0c;如使用synchornized、 ReentrantLock等。 但是在后端集群部署的系统中&#xff0c;程序在不同的JVM虚拟机中运行…

可调整界面输出的桌面万年历设计

可调整界面输出的桌面万年历设计 本文主要介绍月历和生辰八字五行的界面输出方法。一个有趣的方法是可调整界面输出格式&#xff0c;显示几种屏幕排版的布局。本文示例了四个式样。算法的精髓是用一种简单的算法来设置调节屏幕打印输出。分三个显示内容&#xff0c;即月历、大字…

Docker入门实战---修改Docker镜像源

前言 现在大部分互联网公司在实施项目时几乎都会以微服务架构进行落地&#xff0c;那么微服务一旦多了之后就会面临一个如何友好的治理的问题&#xff0c;本人不会重点介绍治理的问题&#xff0c;而是会简单就治理的其中一个环节服务部署运维的问题进行介绍&#xff0c;服务部…

排序算法之桶排序

一、桶排序&#xff08;BucketSort&#xff09; 桶排序&#xff08;Bucket sort&#xff09;或所谓的箱排序&#xff0c;是一个排序算法&#xff0c;工作的原理是将数组分到有限数量的桶里。每个桶再个别排序&#xff08;有可能再使用别的排序算法或是以递归方式继续使用桶排序…

[论文阅读] (28)李沐老师视频学习——1.研究的艺术·跟读者建立联系

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0c;非常欢迎大家给我留言评论&#xff0c;学术路上期…

如何成功申请计算机软件著作权【流程完整记录】

致谢 &#xff1a;此博文的编写包括软著的申请&#xff0c;均借鉴了大佬【万里守约】的博客https://blog.csdn.net/qq_45625499/article/details/123463407 提示&#xff1a;此博文仅适合个人申请&#xff0c;因为我是自己一个人的项目&#xff0c;自己一个人申请软著 文章目录…

2023 Android开发者路线-第一部分

2023 Android开发者路线-第一部分 Android 生态系统处于不断发展的状态&#xff1a;每天都会引入新的库和资料&#xff0c;旨在加快开发速度并让我们作为开发人员的生活更轻松。 在这个由多个部分组成的系列中&#xff0c;您将按照我们的2023 年 Android 开发者路线图了解有关…

pyhton GUI编程之Tkinter美化皮肤ttkbootstrap

文章目录 pyhton GUI编程之Tkinter美化皮肤ttkbootstrap介绍 pyhton GUI编程之Tkinter美化皮肤ttkbootstrap介绍 tkinter 相对简单&#xff0c;学习入门很快&#xff0c;但是做出来的GUI界面不够美观&#xff0c;各个组件的外观都很老土&#xff0c;所谓 " 爱美之心&#…

发现一个国产BI软件,做财务数据分析效果绝了

如果是一般的财务数据分析&#xff0c;BI软件们都能做&#xff0c;但如果真要深入了解财务痛点&#xff0c;逐个击破财务数据分析难点&#xff0c;实现多维立体自助式的财务数据分析&#xff0c;那就难。就目前而言&#xff0c;财务数据分析做得好的国产BI软件也就一个奥威BI软…

使用docker构建ElasticSearch集群

目录 一、准备工作 二、编写docker-compose.yml 三、编写ElasticSearch和kibana的配置文件 四、执行构建ElasticSearch集群 五、验证结果&#xff1a; 六、可视化工具 ElasticSearch可视化工具介绍&#xff08;elasticsearch-head、kibana、elasticHD&#xff09; 一、e…

CTF权威指南 笔记 -第四章Linux安全机制-4.1-Stack Canaries

目录 Stack Canaries 简介 我们进行简单的例子 64 32 checksec Stack Canaries 是对抗栈溢出攻击的技术 SSP安全机制 Canary 的值 栈上的一个随机数 在程序启动时 随机生成并且保存在比返回地址更低值 栈溢出是从低地址向高地址进行溢出 如果攻击者要攻击 就一定要覆…

电动力学专题:圆柱形导体中趋肤效应

电动力学分析 金属导体内的电流密度方程 由Maxwell方程组导出Helmhltz方程 对于良导体,有\sigma/(\omega \eprsilon),因此有 圆柱形导线中电流密度分布 设电流沿Z轴方向流动,均匀导体,可简化为 通解&#xff1a; 安培环路定理 定态电磁波的Maxwell方程组 贝塞尔函数性质&…

【SQL】作为前端,应该了解的SQL知识(第三弹)

&#x1f4d1;视图 使用表时&#xff0c;会将数据保存在存储设备&#xff08;硬盘上&#xff09; 而使用视图时&#xff0c;并不会将数据保存在存储设备上&#xff0c;也不会将数据保存在任何地方。 视图里面保存的是 从表中取出数据所使用的SELECT语句&#xff08;视图中的…

zhangrelay博客置顶三篇点击量分析

230515只有三篇置顶&#xff0c;如下&#xff1a; 分别为&#xff1a; 20.03.13 &#xff1a; 901522.01.12 &#xff1a;1372923.04.15 &#xff1a;18836 熟悉zhangrelay博客风格的AI都清楚&#xff0c;他的博客内容都是筛选和设计过的。 置顶三篇阅读量差值为&#xff1…

C++--AVL树的插入,详解四种旋转规则(结尾附源代码链接)

AVL树的插入 前言左单旋右单旋左右双旋右左双旋检查是否这颗树是否是AVL树 前言 AVL树可以说是对二叉搜索树的优化&#xff0c;我们来看二叉树搜索树的下一面一种特殊情况&#xff1a; 当我们插入的数是上面的情况时&#xff0c;二叉树搜索树的特点就形同虚设了&#xff0c;这…