前端编译、JIT编译、AOT编译

news/2024/4/26 13:24:08/文章来源:https://blog.csdn.net/s178435865/article/details/129171801

一、前端编译:

java设计之初就是强调跨平台,通过javac将源文件编译成于平台无关的class文件, 它定义了执行 Java 程序所需的所有信息(许多Java"语法糖",是在这个阶段完成的,不依赖虚拟机);同时,jvm提供了运行时环境(JRE)——实现了所有特定的本地平台支持(例如:Linux 的 Intel x86 平台、Sun Solaris 平台和 AIX ...的jre)。

Java 程序一个重要部分是字节码序列,它描述了 Java 类中每个方法所执行的操作。字节码使用一个理论上无限大的操作数堆栈来描述计算(操作数堆栈的大小是有限制,但程序极少超出该限制,此外JVM 提供了安全性检查,超出后进行通知),在操作数堆栈上执行的各种操作计算都独立于所有本地处理器的指令集,Java 虚拟机(JVM)规范定义了这些字节码的执行,任何特定本地平台的JRE 都必须遵守 JVM 规范。

因为基于堆栈的本地平台很少(Intel X87 浮点数协处理器是一个明显的例外),所以大多数本地平台不能直接执行 Java 字节码。为了解决这个问题,早期的 JRE 通过解释字节码来执行 Java 程序。即 JVM 在一个循环中重复操作:

获取待执行的下一个字节码;

解码;

从操作数堆栈获取所需的操作数;

按照 JVM 规范执行操作;

将结果写回堆栈。

这一过程称作前端编译。

优点:简单,很方便跨平台,JRE 开发人员只需编写代码来处理每种字节码即可,并且因为用于描述操作的字节码少于 255 个,所以实现的成本比较低;

缺点:性能比较差,因为在运行代码时每次都要重复的解释;

二、JIT编译(即时编译、动态编译):

java设计初衷是使用解释的方式支持应用程序的可移植性目标,早期java运行时提供的性能远低于C/C++之类的编译语言(这类语言尽管性能更高,但生成的代码只能在指定平台上执行),但在过去的十几年中,Java 运行时供应商开发了一些复杂的动态编译器,也称即时编译(Just-in-time,JIT)极大的提升了java运行效率。JIT是在java程序运行时,将最频繁执行的代码(hot spot)编译成本地代码,接下来这些hot spot code直接通过机器码执行,省去了重复解释。JIT执行原理如下图:

1、挑战:

1)JIT这种技术,既保证了程序可移植性又提升了运行效率,但仍会带来运行时性能的下降(因为在程序执行时进行编译,所以编译代码的时间将计入程序的执行时间。任何编写过大型 C 或 C++ 程序的人都知道,编译过程往往较慢)。与之相对应,C++是在运行前编译成本地代码,但这牺牲了移植性。

2)Java 支持动态加载类,这对JIT的设计有着重要的影响。如果待编译代码引用的其他类还没有加载怎么办?比如一个方法需要读取某个尚未加载的类的静态字段值。Java 语言要求第一次执行类引用时加载这个类并将其解析到当前的 JVM 中。直到第一次执行时才解析引用,这意味着没有地址可供从中加载该静态字段。编译器如何处理这种可能性?编译器生成一些代码,用于在没有加载类时加载并解析类。类一旦被解析,就会以一种线程安全的方式修改原始代码位置以便直接访问静态字段的地址,因为此时已获知该地址。

2、优缺点:

1)优点:

Java的动态编译有些时候能够比静态编译语言生成更好的本地代码。现代的 JIT 编译器常常向生成的代码中插入挂钩以收集有关程序行为的信息,以便如果要选择方法进行重编译,就可以更好地优化动态行为。举一个例子:

一个虚方法调用需要查看接收方对象的类调用,以便找出哪个实际目标实现了接收方对象的虚方法。研究表明:大多数虚调用只有一个目标对应于所有的接收方对象,而 JIT 编译器可以为直接调用生成比虚调用更有效率的代码。通过分析代码编译后类层次结构的状态,JIT 编译器可以为虚调用找到一个目标方法,并且生成直接调用目标方法的代码而不是执行较慢的虚调用。当然,如果类层次结构发生变化,并且出现另外的目标方法,则 JIT 编译器可以更正最初生成的代码以便执行虚调用。在实践中,很少需要作出这些更正。另外,由于可能需要作出此类更正,因此静态地执行这种优化非常麻烦。

总之,对于大量的 Java 应用程序来说,动态编译已经弥补了与C++ 之类语言的静态本地编译性能之间的差距,在某些情况下,甚至超过了后者的性能。

2)缺点:

由于识别、编译hot spot code 都需要一定的时间,所以应用程序通常要经历一个准备过程。其次,JIt在运行时也会带来一定的性能损失,有些应用可能无法容忍。

三、AOT编译(静态编译):

由于动态编译技术的多项改进,在很多应用程序中,现代的 JIT 编译器可以产生与 C 或 C++ 静态编译相当的应用程序性能。但是,仍然有很多软件开发人员认为动态编译可能严重干扰程序操作,所以有另外一些开发人员强烈呼吁对 Java 代码进行静态编译(Ahead-of-time AOT),并且坚信那样可以解决性能问题。目的在于避免 JIT 编译器的运行时性能消耗或内存消耗或CPU共享,以及避免解释程序的早期性能开销。

人们希望java能像C++一样在运行之前编译生成本地代码,但不幸的是Java 语言本身的动态特性带来了额外的复杂性,影响了 Java 程序静态编译代码的质量。

1、挑战:

动态类加载是动态 JIT 编译器面临的一个挑战,也是 AOT 编译的一个更重要的问题。只有在执行代码引用类的时候才加载该类。因为是在程序执行前进行 AOT 编译的,所以编译器无法预测加载了哪些类。就是说编译器无法获知任何静态字段的地址、任何对象的任何实例字段的偏移量或任何调用的实际目标,甚至对直接调用(非虚调用)也是如此。在执行代码时,如果证明对任何这类信息的预测是错误的,这意味着一切都将完蛋!

此外,Java 代码可能在程序执行前根本不存在:比如 Java 反射服务通常在运行时生成新类来支持程序的行为。

缺少关于静态、字段、类和方法的信息意味着严重限制了 Java 编译器中优化框架的大部分功能。内联可能是静态或动态编译器应用的最重要的优化,但是由于编译器无法获知调用的目标方法,因此无法再使用这种优化。

2、内联:

内联是一种用于在运行时生成代码避免程序开始和结束时开销的技术,方法是将函数的调用代码插入到调用方的函数中。但是内联最大的益处可能是优化方可见的代码的范围扩大了,从而能够生成更高质量的代码。下面是一个内联前的代码示例:

int foo() { int x=2, y=3; return bar(x,y); }final int bar(int a, int b) { return a+b; }

如果编译器可以证明这个 bar就是 foo()中调用的那个方法,则 bar中的代码可以取代 foo()中对 bar()的调用。这时,bar()方法是 final类型,因此肯定是 foo()中调用的那个方法。甚至在一些虚调用例子中,动态 JIT 编译器通常能够推测性地内联目标方法的代码,并且在绝大多数情况下能够正确使用。编译器将生成以下代码:

int foo() { int x=2, y=3; return x+y; }

2、优缺点:

优点:合理的使用AOT,可以提高运行效率;

缺点:静态(AOT)编译器则牺牲了平台无关性和代码质量,因为它们不能利用程序的动态行为,也不具有关于加载的类或类层次结构的信息。

-----------------------------------

©著作权归作者所有:来自51CTO博客作者赶路人儿的原创作品,请联系作者获取转载授权,否则将追究法律责任

Java编译方式总结:前端编译、JIT编译、AOT编译

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

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

相关文章

01-MySQL基础-简介安装navicat使用SQL(DDL、DML、(DCL)、DML)

文章目录MySQL基础1,数据库相关概念1.1 数据库1.2 数据库管理系统1.3 常见的数据库管理系统1.4 SQL2,MySQL2.1~2.4 mysql安装2.5 MySQL数据模型3,SQL概述3.1 SQL简介3.2 通用语法3.3 SQL分类4,DDL:操作数据库4.1 查询4.2 创建数据…

Java笔记026-集合/数组、Collection接口、ArrayList、Vector、LinkedList

集合集合的理解和好处保存多个数据使用的是数组,分析数组的弊端数组1、长度开始必须指定,而且一旦指定,不能更改2、保存的必须为同一类型的元素3、使用数组进行增加/删除元素的示意代码-比较麻烦Person数组扩容示意代码Person[] pers new Pe…

手把手搭建springboot项目05-springboot整合Redis及其业务场景

目录前言一、食用步骤1.1 安装步骤1.1.1 客户端安装1.2 添加依赖1.3 修改配置1.4 项目使用1.5 序列化二、应用场景2.1 缓存2.2.分布式锁2.2.1 redis实现2.2.2 使用Redisson 作为分布式锁2.3 全局ID、计数器、限流2.4 购物车2.5 消息队列 (List)2.6 点赞、签到、打卡 (Set)2.7 筛…

Liunx服务器安装SVN

一、下载svn安装包链接:https://pan.baidu.com/s/1gkS0tef2kQP6nvXOS64hUw 提取码:cyuw二、SVN安装部署通过sftp将文件拉取到目的主机路径:/usr/package 跳转文件路径: cd /usr/package 执行解压命令:tar -zxvf subversion-1.14.2.tar.gz 执行…

idea启动报错If you already have a 64-bit JDK installed, define a JAVA HOME variable

IDEA启动报错,如下图所示: 解决方法: 1.根据以下路径找到文件idea64.exe.vmoptions ,路径如下图所示: C:\Users\Thinkpad\AppData\Roaming\JetBrains\IntelliJIdea2020.3\idea64.exe.vmoptions 其中Thinkpad是电脑的…

j-vxe-table 下拉搜索选择框数据加载过多导致前端崩溃问题

Jeeg-boot j-vxe-table 下拉搜索选择框数据加载过多导致前端崩溃问题 最近用到了Jeeg-boot j-vxe-table的组件,这组件时真J8难用,还好多BUG,想用个slot插槽也用不了,好像官方写了个基础就没怎么管了。😑 问题&#xf…

JavaEE-初识Servlet

目录Servlet 是什么?完成一个servlet程序1.创建一个maven项目2.引入依赖3.创建目录4.编写Servlet代码5.打包6.部署7.验证程序第三方工具简化Servlet 是什么? Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app. …

阅读笔记7——Focal Loss

一、提出背景 当前一阶的物体检测算法,如SSD和YOLO等虽然实现了实时的速度,但精度始终无法与两阶的Faster RCNN相比。是什么阻碍了一阶算法的高精度呢?何凯明等人将其归咎于正、负样本的不平衡,并基于此提出了新的损失函数Focal L…

支持向量机SVM详细原理,Libsvm工具箱详解,svm参数说明,svm应用实例,神经网络1000案例之15

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 SVM应用实例,基于SVM的股票价格预测 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型&a…

Linux文件系统操作与磁盘管理

查看磁盘和目录的容量 使用 df 命令查看磁盘的容量 df在实验楼的环境中你将看到如下的输出内容: 但在实际的物理主机上会更像这样: 物理主机上的 /dev/sda2 是对应着主机硬盘的分区,后面的数字表示分区号,数字前面的字母 a 表示…

《JeecgBoot系列》 如何设计表单实现“下拉组件二级联动“ ? 以省市二级联动为例

《JeecgBoot系列》 如何设计表单实现"下拉组件二级联动" ? 以省市二级联动为例 一、准备字典表 1.1 创建字典表 CREATE TABLE sys_link_table ( id int NULL, pid int NULL, name varchar(64) null );1.2 准备数据 idpidname1全国21浙江省32杭州市42宁波市51江苏…

投出1000份简历,苦于软件测试没有项目经验,全部石沉大海,辞职5个月,我失业了......

想要找一份高薪的软件测试工作,简历项目必不可少(即使是应届生,你也要写上实习项目)。所以很多自学的朋友找工作时会碰到一个令人颇感绝望的拦路虎:个人并没有实际的项目工作经验怎么办? 怎么办&#xff1f…

Kotlin新手教程九(协程)

一、协程 协程从Kotlin1.3开始引入,本质上协程就是轻量级的线程。协程的基本功能点有: 轻量:可以在单个线程上运行多个协程,因为协程支持挂起,不会使正在运行协程的线程阻塞。挂起比阻塞节省内存,且支持多…

python -- 魔术方法

魔术方法就算定义在类里面的一些特殊的方法 特点:这些func的名字前面都有两个下划线 __new__方法 相当于一个类的创建一个对象的过程 __init__方法 相当于为这个类创建好的对象分配地址初始化的过程 __del__方法 一个类声明这个方法后,创建的对象如果…

缺少IT人员的服装行业该如何进行数字化转型?

服装行业上、下游产业链长,产品属性复杂,是劳动密集型和技术密集型紧密结合的产物,是典型的实体经济代表。 近二十年是服装业发展的机遇和挑战之年,从“世界工厂”“中国制造”,逐渐向“中国设计”转变,中国服装产业经…

c++常用stl算法

1、头文件 这些算法通常包含在头文件<algorithm> <functional> <numeric>中。 2、常用遍历算法 for_each(v.begin(),v.end(), 元素处理函数/仿函数) 注意&#xff1a;在使用transform转存时&#xff0c;目标容器需要提取开辟合适的空间。 void printfunc(…

数学小课堂:数学的线索(从猜想到定理再到应用的整个过程)

文章目录 引言I 勾股定理1.1 勾三股四弦五1.2 数学和自然科学的三个本质差别1.3 总结引言 从猜想到定理再到应用的整个过程是数学发展和体系构建常常经历的步骤。 I 勾股定理 勾股定理: 直角三角形两条直角边的平方之和等于斜边的平方,这个定理在国外都被称为毕达哥拉斯定理…

渗透中超全的Google hack语法

inurl:Login 将返回url中含有Login的网页intitle:后台登录管理员 将返回含有管理员后台的网页intext:后台登录 将返回含有后台的网页inurl:/admin/login.php 将返回含有admin后台的网页inurl:/phpmyadmin/index.php 将返回含有phpmyadmin后台的网页site:http://baidu.com inur:…

云计算|OpenStack|使用VMware安装华为云的R006版CNA和VRM

前言&#xff1a; FusionCompute架构 (CNA、VRM) CNA(ComputingNode Agent):计算节点代理VNA虚拟节点代理&#xff0c;部署在CNA上&#xff0c;实施计算、存储、网络的虚拟化的配置管理。VRM(Virtual Resource Manager):虚拟资源管理器 VNA可以省略不安装 本次实验使用的是V…

还在用chatGPT聊天?《元宇宙2086》已开始用AIGC做漫画连载了!

ChatGPT 是由 OpenAI开发的一个人工智能聊天机器人程序&#xff0c;于 2022 年 11 月推出。该程序使用基于 GPT-3.5架构的大型语言模型并通过强化学习进行训练。 ChatGPT 目前仍以文字方式互动&#xff0c;而除了可以透过人类自然对话方式进行交互&#xff0c;还可以用于相对复…