JVM原理(十八):JVM虚拟机的编译器优化技术

1. 编译器优化技术

编译器的目标虽然是做程序代码翻译为本地机器 码的工作,但其实难点并不在于能不能成功翻译出机器码,输出代码优化质量的高低才是决定编译器优秀与否的关键。

1.1. 优化技术概览

即时编译器对这些代码优化变换是建立在代码的中间表示或者机器码之上的,绝不是直接在Java源码上去做的。

方法内联->冗余访问消除->复写传播->无用代码消除

  1. 最重要的优化技术之一:方法内联

  2. 最前沿的优化技术之一:逃逸分析

  3. 语言无关的经典优化技术之一:公共因子表达式消除

  4. 语言相关的经典优化技术之一:数组边界检查消除

1.2. 方法内联

方法内联可以说是最重要的技术,可以去掉“之一”

作用:除了消除方法调用的成本之外,它更重要的意义是为其他优化手段建立良好的基础。

过程:表面上方法内联的优化行为就是把目标方法的代码原封不动的“复制”到发起调用的方法之中,避免发生真实地方法调用而已。

遇到问题:对于一个虚方法,编译器静态地去做内联的时候很难确定应该使用哪个版本方法版本,在Java选择了在虚拟机中解决这个问题。

解决方法:类型继承关系分析(CHA):这是整个应用程序范围内的类型分析技术,用于确定在目前已加载类中,某个接口是否有多于一种的实现、某个类是否存在子类、某个子类是否覆盖了父类的某个虚方法等信息。

解决过程:

如果是非虚方法,那么直接进行内联就可以了,这种内联是有百分百安全保证的。

如果遇到虚方法,则会向CHA查询此方法在当前程序状态下是否真的有多个目标版本可供选择,如果查询到只有一个版本,那就可以假设“应用程序的全貌就是现在运行的这个样子”来进行内联,这种内联被称为守护内联,内置“逃生门”,如果当前条件不成立,就会退回到解释状态进行执行。

内联缓存:如果该方法确实有多个版本的目标方法可供选择,那即时编译器还将进行最后一次努力,使用内联缓存的方式来缩减方法调用的开销。

工作原理:在未发生方法调用之前,内联缓存状态为空,当第一次调用发生后,缓存记录下方法接收者的版本信息,并且每次进行方法调用时都比较接收者的版本。如果以后进来的每次调用的方法接收者版本都是一样的,那么这时他就是一种单态内联缓存。通过该缓存来调用,比用不内联的非虚方法调用,仅多了一次类型判断的开销而已。

通过该缓存来调用,比用不内联的非虛方法调用,仅多了一次类型判断的开销而已。但如果真的出现方法接收者不一致的情况,就说明程序用到了虛方法的多态特性,这时候会退化成超多态内联缓存(Megamorphic Inline Cache),其开销相当于真正查找虚方法表来进行方法分派。

1.3. 逃逸分析

逃逸分析的基本原理是:分析对象动态作用域,当一个对象在方法里面被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他方法中,这种称为方法逃逸;甚至还有可能被外部线程访问到,譬如赋值给可以在其他线程中访问的实例变量,这种称为线程逃逸;从不逃逸、方法逃逸到线程逃逸,称为对象由低到高的不同逃逸程度

由逃逸程度从高到底,虚拟机会采取不同的优化:

栈上分配:如果确定一个象不会逃逸出线程之外,那让这个对象在栈上分配内存将会是一个很不错的主意,对象所占用的内存空间就可以随栈帧出栈而销毁。在一般应用中,完全不会逃逸的局部对象和不会逃逸出线程的对象所占的比例是很大的,如果能使用栈上分配,那大量的对象就会随着方法的结束而自动销毁了,垃圾收集子系统的压力将会下降很多。栈上分配可以支持方法逃逸,但不能支持线程逃逸,(将对象分配到栈上,这个思想很不错)。

标量替换:

  1. 标量:若一个数据已经无法再分解成更小的数据来表示了,Java虛拟机中的原始数据类型(int、long等数值类型及reference类型等)都不能再进一步分解了,那么这些数据就可以被称为标量。

  2. 聚合量:如果一个数据可以继续分解,那么它就被称为聚合量。

工作原理:

假如逃逸分析能够证明一个对象不会被方法外部访问,并且这个对象可以被拆散,那么程序真正执行的时候将可能不去创建这个对象,而改为直接创建它的若干个被这个方法使用的成员变量来代替。将对象拆分后,除了可以让对象的成员变量在栈上(栈上存储的数据,很大机会被虛拟机分配至物理机器的高速寄存器中存储)分配和读写之外,还可以为后续进一步的优化手段创建条件。

标量替换可以看作栈上分配的一种特殊案例,实现更简单,但对逃逸程度的要求更高,他不允许对象逃逸出方法范围内。

同步消除:

线程同步本身是一个相对耗时的过程,如果逃逸分析能够确定一个变量不会逃逸出线程,无法被其他线程访问,那么这个变量的读写肯定就不会有竞争,对这个变量实施的同步措施也就可以安全地消除掉。

不成熟的原因:不成熟的原因主要是逃逸分析的计算成本非常高,甚至不能保证逃逸分析带来的性能收益会高于它的消耗,尤其是大型程序中反而发现实施逃逸分析可能出现效果不稳定的情况。如果逃逸分析完毕后发现几乎找不到几个不逃逸的对象,那这些运行器好用的时间就白白浪费了。

1.4. 公共子表达式消除

公共子表达式:如果一个表达式E之前已经被计算过了,并且从先前的计算到现在E中所有变量的值都没有发生变化,那么E的这次出现就称为公共子表达式。

1.5. 数组边界检查消除

超出边界抛出异常

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Android Studio点餐项目,点餐app

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 实现登录、注册、注销功能,退出登录等功能, 以及基本的选择店铺点餐,加入购物车和结算等功能,以及可以增加或者减少商品的个数, 同时可以同步价格的总量。以…

两年经验前端带你重学前端框架必会的ajax+node.js+webpack+git等技术的个人学习心得、作业及bug记录 Day1

黑马程序员前端AJAX入门到实战全套教程,包含学前端框架必会的(ajaxnode.jswebpackgit),一套全覆盖 Day1 你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​…

沙龙回顾|MongoDB如何充当企业开发加速器?

数据不仅是企业发展转型的驱动力,也是开发者最棘手的问题。前日,MongoDB携手阿里云、NineData在杭州成功举办了“数据驱动,敏捷前行——MongoDB企业开发加速器”技术沙龙。此次活动吸引了来自各行各业的专业人员,共同探讨MongoDB的…

大话C语言:第27篇 内存模型

1 存储硬件概述 现代计算机遵循冯诺依曼体系结果,存储分为: 外部存储器:长期存放数据,掉电不丢失数据。例如,硬盘、flash、rom、u 盘、光盘、磁带。 内部存储器:暂时存放数据,掉电数据丢失。例…

小白学python(第六天)循环之异变

本篇文章给大家讲解的是循环语句,那么闲话少叙,我们进入正题 在c、Java中循环都是三剑客,那么大家可还记得是哪三位剑客吗 剑客一:while循环 剑客二:for循环 剑客三:do{……}while(&…

springcloud-alibba之FeignClient

代码地址&#xff1a;springcloud系列: springcloud 组件分析拆解 1.FeignClient的集成 springboot版本&#xff1a;3.1.5 springcloud组件版本&#xff1a;2022.0.4 nacos客户端的版本&#xff1a;2.3.2 1.引pom 这里引入了nacos和feginclient的版本 <dependency>…

MongoDB 单节点升级为副本集高可用集群(1主1从1仲裁)

作者介绍&#xff1a;老苏&#xff0c;10余年DBA工作运维经验&#xff0c;擅长Oracle、MySQL、PG、Mongodb数据库运维&#xff08;如安装迁移&#xff0c;性能优化、故障应急处理等&#xff09; 公众号&#xff1a;老苏畅谈运维 欢迎关注本人公众号&#xff0c;更多精彩与您分享…

SpringBoot 实现视频分段播放(通过进度条来加载视频)

需求&#xff1a;现在我本地电脑中有一个文件夹&#xff0c;文件夹中都是视频&#xff0c;需要实现视频播放的功能。 问题&#xff1a;如果通过类似 SpringBoot static 文件夹的方式来实现&#xff0c;客户端要下载好完整的视频之后才可以播放&#xff0c;并且服务端也会占用大…

计算机网络之以太网

上文内容&#xff1a;总线局域网以及冲突的解决方法 1.以太网的起源 1.1起源 60年代末期&#xff0c;夏威夷大学Norman Abramson等研制ALOHA无线网络系统,实现Oahu岛上的主机和其它岛及船上的读卡机和终端通信&#xff1b; 出境信道地址&#xff1a;主机到终端&#xff1…

vue3 + 百度地图 实现多坐标生成轨迹的两种种方式

本次依然是关于百度地图中常见的一个问题&#xff0c;此次共使用了两种方式并做了一些分析及处理&#xff0c;希望有所帮助。如有问题可以评论或私信。 一、便捷方式 优点&#xff1a;便捷&#xff0c;所用的api方法是根据坐标进行计算后绘制路线&#xff0c;所以路线相对准确…

制定事件响应计划的四个关键步骤,如何做到风险闭环

一个有效的安全事件响应策略的关键组成部分有哪些&#xff1f;一个有效的安全事件响应策略包括四个关键组成部分&#xff0c;它们协同工作以确保对网络安全问题的快速和有效响应。 一个有效的安全事件响应策略的关键组成部分有哪些&#xff1f; 一个有效的安全事件响应策略包括…

Java常用算法集合扩容机制分析

基础篇 基础篇要点&#xff1a;算法、数据结构、基础设计模式 1. 二分查找 要求 能够用自己语言描述二分查找算法能够手写二分查找代码能够解答一些变化后的考法 算法描述 前提&#xff1a;有已排序数组 A&#xff08;假设已经做好&#xff09; 定义左边界 L、右边界 R&…

SQLite 命令行客户端 + Windows 批处理应用

SQLite 命令行客户端 Windows 批处理应用 下载 SQLite 客户端1. Bat 辅助脚本1. 执行SQL.bat执行 2. 导出Excel.bat执行效果 3. 导出HTML.bat执行效果 4. 清空-订单表.bat 2. 测试 SQL1. 创建订单表.sql2. 插入订单表.sql3. 查询订单表.sql4. 清空订单表.sql5. 删除订单表.sql…

linux驱动编程 - kfifo先进先出队列

简介&#xff1a; kfifo是Linux Kernel里面的一个 FIFO&#xff08;先进先出&#xff09;数据结构&#xff0c;它采用环形循环队列的数据结构来实现&#xff0c;提供一个无边界的字节流服务&#xff0c;并且使用并行无锁编程技术&#xff0c;即当它用于只有一个入队线程和一个出…

黑马的ES课程中的不足

在我自己做项目使用ES的时候&#xff0c;发现了黑马没教的方法&#xff0c;以及一些它项目的小问题 搜索时的匹配方法 这个boolQuery().should 我的项目是通过文章的标题title和内容content来进行搜索 但是黑马它的项目只用了must 如果我们的title和content都用must&#x…

Arc for Windows 无法使用?一篇文章教会你!

&#x1f44b; 大家好&#xff0c;我是 Beast Cheng &#x1f4eb; 联系我&#xff1a;458290771qq.com &#x1f331; 接合作、推广…… 什么是Arc浏览器&#xff1f; Arc浏览器是The Browser Conpany使用Swift语言开发的一款浏览器&#xff0c;Arc浏览器由其漂亮的侧边栏闻名…

HTML5使用<mark>标签:高亮显示文本

1、<mark>标签的使用 mark 标签用于表示页面中需要突出显示或高亮的一段文本&#xff0c;这段文本对于当前用户具有参考作用。它通常在引用原文以引起读者注意时使用。<mark>标签的作用相当于使用一支荧光笔在打印的纸张上标出一些文字。它与强调不同&#xff0c;…

自闭症在生活中的典型表现

自闭症&#xff0c;这个看似遥远却又悄然存在于我们周围的疾病&#xff0c;其影响深远且复杂。在日常生活中&#xff0c;自闭症患者的典型表现往往让人印象深刻&#xff0c;这些表现不仅揭示了他们内心的世界&#xff0c;也提醒我们要以更加包容和理解的心态去面对他们。 首先…

UEC++ 虚幻5第三人称射击游戏(二)

UEC++ 虚幻5第三人称射击游戏(二) 派生榴弹类武器 新建一个继承自Weapon的子类作为派生榴弹类武器 将Weapon类中的Fire函数添加virtual关键字变为虚函数让榴弹类继承重写 在ProjectileWeapon中重写Fire函数,新建生成投射物的模版变量 Fire函数重写逻辑 代码//生成的投射物U…