Java --- JVM的执行引擎
目录
一、执行引擎概述
1.1、执行引擎的工作过程
二、Java代码编译和执行的过程
三、解释器
3.1、解释器工作机制
3.2、解释器分类
3.3、解释器现状
四、JIT编译器
五、热点代码及探测方式
六、方法调用计数器
6.1、热点衰减
七、回边计数器
八、HotSpot VM设置程序执行方式
8.1、HotSpot VM中JIT分类
8.2、C1和C2编译器不同优化策略
8.2.1、分层编译策略
一、执行引擎概述
1、执行引擎是Java虚拟机核心的组成部分之一。
2、“虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式。
3、JVM的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之土,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被JVM所识别的字节码指令、符号表,以及其他辅助信息。
4、那么,如果想要让一个Java程序运行起来,执行引擎(Execution Engine)的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以。简单来说,JVM中的执行引擎充当了将高级语言翻译为机器语言的译者。
1.1、执行引擎的工作过程
1、执行引擎在执行的过程中究竟需要执行什么样的字节码指令完全依赖于PC寄存器。
2、每当执行完一项指令操作后,PC寄存器就会更新下一条需要被执行的指令地址。
3、当然方法在执行的过程中,执行引擎有可能会通过存储在局部变量表中的对象引用准确定位到存储在Java堆区中的对象实例信息,以及通过对象头中的元数据指针定位到目标对象的类型信息。
小结:从外观上来看,所有的Java虚拟机的执行引擎输入、输出都是一致的:输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行结果。
二、Java代码编译和执行的过程
大部分的程序代码转换成物理机的目标代码或虚拟机能执行的指令集之前,都需要经过上图中的各个步骤。
Java代码编译是由Java源码编译器来完成。
Java字节码的执行是由JVM执行引擎来完成。
什么是解释器(Interpreter),什么是JIT编译器?
解释器:当Java虚拟机启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条子节码文件中的内容“翻译”为对应平台的本地机器指令执行。
JIT (Just In Time Compiler)编译器:就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言。
为什么Java是半编译半解释型语言?
JDK1.0时代,将Java语言定位为“解释执行”还是比较准确的。再后来,Java也发展出可以直接生成本地代码的编译器。
现在JVM在执行Java代码的时候,通常都会将解释执行与编译执行二者结合起来讲行。
三、解释器
JVM设计者们的初衷仅仅只是单纯地为了满足Java程序实现跨平台特性,因此避免采用静态编译的方式直接生成本地机器指令,从而诞生了实现解释器在运行时采用逐行解释字节码执行程序的想法。
3.1、解释器工作机制
解释器真正意义上所承担的角色就是一个运行时“翻译者”,将字节码文件中的内容“翻译”为对应平台的本地机器指令执行。
当一条字节码指令被解释执行完成后,接着再根据Pc寄存器中记录的下一条需要被执行的字节码指令执行解释操作。
3.2、解释器分类
在Java的发展历史里,一共有两套解释执行器,即古老的字节码解释器、现在普遍使用的模板解释器。
字节码解释器在执行时通过纯软件代码模拟字节码的执行,效率非常低下。
而模板解释器将每一条字节码和一个模板函数相关联,模板函数中直接产生这条字节码执行时的机器码,从而很大程度上提高了解释器的性能。
在HotSpot VM中,解释器主要由Interpreter模块和Ctode模块构成。
Interpreter模块:实现了解释器的核心功能
Code模块:用于管理HotSpot VM在运行时生成的本地机器指令
3.3、解释器现状
1、由于解释器在设计和实现上非常简单,因此除了Java语言之外,还有许多高级语言同样也是基于解释器执行的,比如Python、Perl、Ruby等。但是在今天,基于解释器执行已经沦落为低效的代名词,并且时常被一些C/C++程序员所调侃。|
2、为了解决这个问题,JVM平台支持一种叫作即时编译的技术。即时编译的目的是避免函数被解释执行,而是将整个函数体编译成为机器码,每次函数执行时,只执行编译后的机器码即可,这种方式可以使执行效率大幅度提升。
3、不过无论如何,基于解释器的执行模式仍然为中间语言的发展做出了不可磨灭的贡献。
四、JIT编译器
1、Java语言的“编译期” 其实是一段“不确定”的操作过程,因为它可能是指一个前端编译器,把.java文件转变成.class文件的过程。
2、也可能是指虚拟机的后端运行编译器(JIT 编译器,Just In Time Compiler)把字节码转变成机器码的过程。
3、还可能是指使用静态提前编译器(AOT 编译器,Ahead Of Time Compiler)直接把.java文件编译成本地机器代码的过程。
前端编译器: Sun 的 Javac、Eclipse JDT 中的增式编译器(ECJ)。
JIT编译器: HotSpot VM 的 C1 、C2编译器。
AOT编译器:GNU Compiler for the Java (GCJ)、Excelsior JET。
五、热点代码及探测方式
当然是否需要启动JIT编译器将字节码直接编译为对应平台的本地机器指令,则需要根据代码被调用执行的频率而定。关于那些需要被编译为本地代码的字节码,也被称为“热点代码”,JIT编译器在运行时会针对那些频繁被调用的“热点代码”做出深度优化,将其直接编译为对应平台的本地机器指令,以此提升Java程序的执行性能。
1、一个被调用多次的方法,或者是一个方法体内部循环次数较多的循环体都可以被称为“热点代码”,因此都可以通过JIT编译器编译为本地机器指令,由于这种编译方式发生在方法的执行过程中,因此也被称为栈上替换,或简称为OSR(On Stack Replacement)。
2、一个方法究竟被调用多少次,或者一个循环究竟需要执行多少次循环才可以达到这个标准?必须需要一个明确的阈值,JIT编译器才会将这些“热点代码”编译为本地机器指令执行,主要依靠热点探测功能。
3、目前HotSpot VM所采用的热点探测方式是基于计数器的热点探测。
4、采用基于计数器的热点探测,HotSpot VM将会为每一个方法建立2个不同类型的计数器,分别为方法调用计数器(Invocation Counter)和回边计数器(Back Edge Counter)。
①、方法调用计数器用于统计方法的调用次数。
②、回边计数器则用于统计循环体执行的循环次数。
六、方法调用计数器
1、这个计数器就用于统计方法被调用的次数,它默认阈值在Client模式下是1500次,在Server模式下是10000次。超过这个阈值,就会触发JIT阈值。
2、这个阈值可以通过虚拟机参数-XX:CompileThreshold来人为设定。
3、当一个方法被调用时,会先检查该方法是否存在被JIT编译过的版本,如果存在,则优先使用编译后的本地代码来执行。如果不存在已被编译过的版本,则将此方法的调用计数器值加1,然后判断方法调用计数器与回边计数器值之和是否超过方法调用计数器的阈值。如果已超过阈值,那么将会向即时编译器提交一个该方法的代码编译请求。
6.1、热点衰减
1、如果不做任何设置,方法调用计数器统计并不是方法调用的绝对次数,而是一个相对的执行频率,即一段时间之内方法被调用的次数。当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器编译,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器就会被减少一半,这个过程被称为方法调用计数器热度的衰减(Counter Decay),而这段时间就称为此方法统计的半衰周期(Counter Half Life Time)。
2、进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数-XX:-UseCounterDecay来关闭热度衰减,让方法计数器统计方法调用的绝对次数,这样,只要系统运行时间足够长,绝大部分方法都会被编译为本地代码。
3、可以使用-XX:CounterHalfLifeTime参数设置半衰周期的时间,单位是秒。
七、回边计数器
作用是统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为“回边”(Back Edge).显然,建立回边计数器统计的目的就是为了触发OSR编译。
八、HotSpot VM设置程序执行方式
缺省情况下HotSpot VM是采用解释器与即时编译器并存的架构,开发人员也可以根据具体情况的应用场景,通过命令显式地为Java虚拟机指定在运行时到底是完全采用解释器执行,还是完全采用即时编译器执行。
①、-Xint:完全采用解释器模式执行程序;
②、-Xcomp:完全采用即时编译器模式执行程序。如果即时编译出现问题,解释器会介入执行。
③、-Xmixed:采用解释器+即时编译器的混合模式共同执行程序。
参考代码:
public class IntCompTest {public static void main(String[] args) {long start = System.currentTimeMillis();testPrimeNumber(1000000);long end = System.currentTimeMillis();//-Xint:11740ms -Xcomp:446ms -Xmixed:438msSystem.out.println("花费的时间为:" + (end - start));}public static void testPrimeNumber(int count){for (int i = 0; i < count; i++) {//计算100以内的质数for (int j = 2; j <= 100 ; j++) {for (int k = 2; k <= Math.sqrt(j); k++) {if (j % k == 0){continue;}}}}}
}
8.1、HotSpot VM中JIT分类
在HotSpot VM中内嵌有两个JIT编译器,分别为Client Compiler和Server Compiler,但大多数情况下简称C1编译器和C2编译器。可以通过命令显式指定Java虚拟机在运行时到底使用哪一种即时编译器。
1、-client:指定Java虚拟机运行在Client模式下,并使用C1编译器。C1编译器会对字节码进行简单和可靠的优化,耗时短。以达到更快的编译速度。
2、-server:指定Java虚拟机运行在Server模式下,并使用C2编译器。C2进行耗时较长的优化,以及激进优化。但优化的代码执行效率更高。
8.2、C1和C2编译器不同优化策略
1、在不同的编译器上有不同的优化策略,C1编译器上主要有方法内联,去虚拟化、冗余消除。
①、方法内联:将引用的函数代码编译到引用点处,这样可以减少栈帧的生成,减少参数传递以及跳转过程。
②、去虚拟化:对唯一的实现类进行内联。
③、冗余消除:在运行期间把一些不会执行的代码折叠掉。
2、C2的优化主要是在全局层面,逃逸分析是优化的基础。基于逃逸分析在C2上有如下几种优化:
①、标量替换:用标量值代替聚合对象的属性值
②、栈上分配:对于未逃逸的对象分配对象在栈而不是在堆。
③、同步消除:消除同步操作,通常指synchronized
8.2.1、分层编译策略
程序解释执行(不开启性能监控)可以触发C1编译,将字节码编译成机器码,可以进行简单优化,也可以加上性能监控,C2编译会根据性能监控信息进行激进优化。
在Java7版本后,开发人员在程序中显示指定命令”-server“时,默认将会开启分层策略,由C1编译器和C2编译器相互协作共同来执行编译任务。
总结:1、一般情况下,JIT编译出来的机器码性能比解释器高。2、C2编译器启动时长比C1编译器慢,系统稳定执行以后,C2编译器执行速度远远快于C1编译器。
相关文章:

Java --- JVM的执行引擎
目录 一、执行引擎概述 1.1、执行引擎的工作过程 二、Java代码编译和执行的过程 三、解释器 3.1、解释器工作机制 3.2、解释器分类 3.3、解释器现状 四、JIT编译器 五、热点代码及探测方式 六、方法调用计数器 6.1、热点衰减 七、回边计数器 八、HotSpot VM设置程序…...

前端学习笔记--node.js
Node Node 可以理解成 ECMAScript 内置的模块组成的,引用第三方模块, npm系统 node package manager。 node是基于js的,前端来写服务端通过node是最方便的,node的性能问题 内部采用的多线程。 node中主线程还是单线程的 &#…...

DB2 常用命令及SQL语句
前言 DB2数据库是由IBM开发的关系型数据库管理系统(RDBMS)。它是一种功能强大、可扩展和可靠的数据库解决方案,用于存储和管理企业级应用程序的数据。 以下是一些关于DB2数据库的重要信息和特点: 数据模型:DB2数据库…...

spring-boot-starter-data-redis2.X连接redis7
由于redis7引入了acl机制,可以配置用户权限, 比如配置了一个普通用户 test,权限为 test_ 前缀的key可操作 springboot想要连接,并没有设置用户名的地方, 跟了源码,jedis客户端是支持的,但是s…...

PHP中$_SERVER全局变量
在PHP中,$_SERVER 是一个全局数组变量,它包含了有关服务器和当前脚本的信息。$_SERVER 数组中的每个元素都是服务器环境的一个参数,如请求的方法、请求的 URI、客户端 IP 地址等。 PATH 系统环境变量的值,包含了多个目录的路径…...

【ML】欠拟合和过拟合的一些判别和优化方法(吴恩达机器学习笔记)
吴恩达老师的机器学习教程笔记 减少误差的一些方法 获得更多的训练实例——解决高方差尝试减少特征的数量——解决高方差尝试获得更多的特征——解决高偏差尝试增加多项式特征——解决高偏差尝试减少正则化程度 λ——解决高偏差尝试增加正则化程度 λ——解决高方差 什么是…...

服务器数据恢复—服务器发生故障导致数据丢失如何恢复服务器数据?
服务器常见故障: 硬件故障:磁盘、板卡、电源故障等。 软件故障:操作系统崩溃、程序运行错误等。 入侵破坏:加密、删除服务数据等。 不可控力:浸水、火烧、倒塌等。 误操作:格式化、删除、覆盖等。 如何减少…...

SLAM中提到的相机位姿到底指什么?
不小心又绕进去了,所以掰一下。 以我个人最直观的理解,假设无旋转,相机在世界坐标系的(5,0,0)^T的位置上,所谓“位姿”,应该反映相机的位置,所以相机位姿应该如下: Eigen::Matrix4d T Eigen::M…...

《视觉SLAM十四讲》-- 后端 1(上)
文章目录 08 后端 18.1 概述8.1.1 状态估计的概率解释8.1.2 线性系统和卡尔曼滤波(KF)8.1.3 非线性系统和扩展卡尔曼滤波(EKF)8.1.4 小结 08 后端 1 前端视觉里程计可以给出一个短时间内的轨迹和地图,但由于不可避免的…...

南昌市西湖区棒球特色规划
西湖区棒球特色学校打造方案 一、项目背景 南昌市西湖区作为江西省的教育强区,一直致力于发展特色教育。近年来,棒球运动逐渐受到广泛关注,西湖区决定将棒球运动作为特色项目,打造一所具有国际水平的棒球特色学校。 二、目标与…...

nginx启动命令
普通启动 切换到nginx安装目录的sbin目录下,执行:./nginx 通过配置文件启动 ./nginx -c /usr/local/nginx/conf/nginx.conf /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 其中-c是指定配置文件,而且配置文件路径必须指定绝对路…...

防爆五参数气象仪的科技力量
WX-FBQ2 随着科技的不断进步,气象监测设备也在不断升级和完善。 防爆五参数气象仪是一种可以同时监测温度、湿度、压力、风速和风向五个基本气象参数的仪器。它采用了气象监测技术,不仅可以实时监测气象数据,还可以对数据进行分析和处理。 …...

J. Chem. Theory Comput. | AI驱动的柔性蛋白-小分子复合物建模
今天为大家介绍的是来自陈语谦教授团队发表在Journal of Chemical Theory and Computation的论文,“Equivariant Flexible Modeling of the Protein−Ligand Binding Pose with Geometric Deep Learning”,博士生董铁君为第一作者。该文提出了一种新的AI…...

数据库sql语句设置外键
当我们需要在数据库表之间建立关联关系时,可以使用外键(Foreign Key)来实现。在 SQL 中,外键可以用来保持数据的完整性,并帮助我们更有效地管理数据。以下是设置外键的步骤: 1.在创建表时,需要…...

excel在函数中插入函数
例如,要计算RAND()1的值,其中RAND()表示取0~1之间的随机数。 插入-》函数: 选SUM函数: 点击“继续”: 将光标先放在数字1中的输入框中,然后在左边过滤出RAND函数,并且点击继续࿱…...

保姆级前端翻牌效果(CSS)
效果 翻牌效果 hover 时候 代码直接上 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…...

Mac环境配置的相关知识
Mac中配置环境的三个途径: 1.open/vim /etc/profile (建议不修改这个文件)全局(公有)配置,不管是哪个用户,登录时都会读取该文件(一般在这个文件中添加系统级环境变量) 2./etc/bashrc全局(公有)配置,bash shell执行时࿰…...

业务连续性:确保稳健运营的关键战略
在今天的快节奏商业环境中,保障业务连续性是企业成功的重要保障。业务连续性不仅仅是关于应对自然灾害或技术故障,更是一项战略,涉及组织的整体准备、规划和应对能力,以确保在各种情况下业务的稳健运营。 一、业务连续性的定义 业…...

【Pytorch和深度学习】栏目导读
一、栏目说明 本栏目《pytorch实践》是为初学者入门深度学习准备的。本文是该栏目的导读部分,因为计划本栏目在明年完成,因此,导读部分,即本文也在持续更新中。 本栏目设计目标是将深度学习全面用pytorch实践一遍,由浅…...

sklearn笔记:neighbors.NearestNeighbors
1 最近邻 class sklearn.neighbors.NearestNeighbors(*, n_neighbors5, radius1.0, algorithmauto, leaf_size30, metricminkowski, p2, metric_paramsNone, n_jobsNone)邻居搜索算法的选择通过关键字 algorithm 控制,它必须是 [auto, ball_tree, kd_tree, brute] …...

V-for中 key 值的作用,如何选择key
Vue.js 中的 v-for 指令是一个强大的工具,可以用于循环渲染列表数据。在使用 v-for 指令时,我们经常需要为每个循环项指定一个 key 值。本文将深入探讨 key 值的作用,并为您提供如何选择 key 值的建议和指导。 开始 在开始之前,让…...

linux内核驱动开发
系列文章目录 主要介绍linux系统下的驱动开发 文章目录 系列文章目录 文章目录 前言 一、驱动是什么? 二、主要分类 2.读入数据 3.代码示例 总结 前言 对设备驱动最通俗的解释就是“驱使硬件设备行动”。驱动与底层硬件直接打交道,按照硬件设备的具体工作方式,读写…...

2.3.5 交换机的VRRP技术
实验2.3.5 交换机的VRRP技术 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施1.交换机的基本配置 六、任务验收七、任务小结 一、任务描述 某公司的网络核心层原来采用一台三层交换机,随着网络应用的日益增多,对网络的可靠性也提出了越来…...

Knowledge Graph Reasoning with Relational Digraph
摘要: 知识图推理的目的是从已有的事实中推断出新的事实。基于关系路径的推理方法具有较强的可解释性和可转移性。然而,路径在捕获图中的局部证据方面自然受到限制。在本文中,我们引入了一种新的关系结构,即关系有向图(r-digraph)࿰…...

力扣203:移除链表元素
力扣203:移除链表元素 题目描述: 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出&a…...

Moto edge s pro手机 WIFI和蓝牙连接不上 解决方法分享
2021年12月入手一台Moto Edge S Pro 12256版,看着性价比很高,越用越垃圾。屏幕显示没有vivo亮丽/APP图标很丑/屏幕上一点点水就失灵/拍照片边缘是模糊的/系统几乎不更新。 以上都可以忍受,但是: 用一年不到,蓝牙不能…...

两万字图文详解!InnoDB锁专题!
前言 本文将跟大家聊聊 InnoDB 的锁。本文比较长,包括一条 SQL 是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。 为什么需要加锁呢? InnoDB 的七种锁介绍 一条 SQL 是…...

2023湖南省赛
连接 目录 A:开开心心233 B:Square Game C:室温超导 F:necklace I:hard math J:radius K:tourist 补题中,会给出大部分代码 A:开开心心233 签到题 ,无论二分还是解方程还是直接for循环枚举都能直接通过啦 signed main() {ios_base:…...

AISchedule(3):基础生成表格
<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>事件列表</title><!-- 加载样式表 --><style>/* 基础样式 */body {background: linear-gradient(to bottom, #f2f2f2, #e0e0e0);font-family: Helvetica…...

OpenAI 上线新功能力捧 RAG,开发者真的不需要向量数据库了?
近期, OpenAI 的开发者大会迅速成为各大媒体及开发者的热议焦点,有人甚至发出疑问“向量数据库是不是失宠了?” 这并非空穴来风。的确,OpenAI 在现场频频放出大招,宣布推出 GPT-4 Turbo 模型、全新 Assistants API 和一…...