“同声传译”还是“全文翻译”?为何HotSpot虚拟机仍要保留解释器?
Java虚拟机采用的是基于栈的指令集架构,这意味着Java虚拟机主要通过解释执行基于栈的字节码来运行Java程序。尽管Java虚拟机采取了一些优化措施,如栈顶缓存(Stack Top Cache),将栈顶元素缓存到寄存器中以减少对内存的频繁访问,但这些优化手段并不能从根本上解决基于栈的指令集执行效率相对较低的问题。
因此,对字节码的编译和执行优化成为了提升Java虚拟机性能的一个关键环节。
Java编译过程可以被划分为前端编译(Source-to-Bytecode)和后端编译(Bytecode-to-NativeCode)两个阶段。前端编译主要负责将Java源代码(.java文件)转化为中间表示形式的Java字节码(.class文件)。在这个阶段,Java编译器(javac)不仅会进行语法和语义的检查,还会进行一些编译优化,例如,自动装箱/拆箱(Integer i = 10转换为Integer i = Integer.valueOf(10))、泛型擦除(Generics Erasure)、增强for循环(Enhanced for-loop)转换为迭代器或索引循环、Lambda表达式转换为内部类或invokedynamic、条件编译(未满足条件的代码块会被消除)等。
后端编译则负责将中间表示形式转化为特定硬件平台的本地机器码。Java编译器的性能优化主要在后端的即时编译器(Just-In-Time Compiler, JIT)完成。
Java虚拟机最初主要依赖解释器(Interpreter)来逐条执行字节码指令。但为了追求更高的执行效率,现代主流Java虚拟机(如Oracle HotSpot, OpenJDK HotSpot)引入了热点探测(Hot Spot Detection)机制和即时编译器。
解释执行

尽管即时编译的执行效率高于解释执行,但如HotSpot虚拟机普遍采用的是解释器和编译器并存的混合执行模式(Mixed Mode)。解释器在Java虚拟机的整体性能策略中扮演着不可或缺的角色。
1)快速启动与响应:解释器无需等待编译完成即可立即执行字节码,这使得Java应用程序能够快速启动。对于GUI应用、短时运行的工具或需要快速响应的场景,这一点尤为重要。
2)较低的内存占用:解释执行时,Java虚拟机本身和解释器占用的内存相对较小。即时编译器自身需要消耗内存,并且编译后的本地代码也需要存储在代码缓存(Code Cache)中。在内存资源极为受限的环境下,解释执行更具优势。
3)实现的相对简单性:解释器的实现逻辑通常比即时编译器(尤其是进行复杂优化的编译器如C2)简单,便于Java虚拟机开发者维护和调试。
4)逆优化(Deoptimization)——“逃生门”机制:即时编译器有时会进行一些激进的、推测性的优化(Speculative Optimizations)。例如,基于当前加载的类层次结构进行方法内联。如果后续加载了新的类,导致之前的优化假设不再成立(例如,一个被内联的虚方法被意外重写),Java虚拟机需要能够撤销这些无效的优化,退回到解释执行状态或重新编译。这个过程称为逆优化,它是保证程序正确性和即时编译敢于进行激进优化的重要保障。

提前编译器
提前编译器(Ahead-of-Time Compiler,AOT)是一种在程序运行前将字节码预先转换为本地机器码的编译策略。与即时编译形成对比,提前编译的主要优势在于减少了运行时的编译开销,从而提高了程序的启动速度。这种策略属于静态编译方法。
然而,Java语言的动态特性为提前编译带来了额外的复杂性,这可能会影响静态编译代码的质量和效率。例如,Java的动态类加载、反射、invokedynamic等特性使得提前编译器难以在编译时获取程序的全部信息。此外,尽管提前编译器能够将整个程序的代码预先编译成机器码,但其编译质量往往无法与即时编译器尤其是C2)通过运行时性能分析对热点代码进行的优化相媲美。
提前编译器的存在主要是为了减轻即时编译器的运行时性能消耗或内存消耗,或者避免解释执行的早期性能开销。在运行速度上,提前编译生成的代码通常比即时编译慢,但比解释执行快。在编译时间上,提前编译通常需要更多的时间。因此,提前编译可以被视为Java虚拟机在编译质量和性能之间进行权衡的一种策略。
对于解释执行、即时编译和提前编译,它们在编译开销和编译质量上的对比如下。
1)运行时编译开销(从低到高):解释执行(几乎无) < 提前编译(预编译,运行时低) < 即时编译(运行时编译,有开销)。
2)编译质量/峰值性能(从高到低):即时编译(C2, 带Profiling) > 提前编译(可能优于C1,但通常不如C2) > 解释执行。
当前,更成功的提前编译实践体现在如GraalVM Native Image这样的技术中。它通过更严格的构建时分析(需要指定所有运行时可达的代码)和特定的运行时支持,能够将Java应用编译成自包含的、启动极快的本地可执行文件,但也有其使用限制(如对动态特性的支持需要配置)。

未完待续
很高兴与你相遇!如果你喜欢本文内容,记得关注哦!!
“同声传译”还是“全文翻译”?为何HotSpot虚拟机仍要保留解释器?的更多相关文章
- 微信小程序使用同声传译实现语音识别功能
我使用同声传译语音识别功能是为了实现微信小程序首页的语音搜索功能,如果你也是那么恭喜你,你可以ctrl+c.ctrl+v再改一改,如果你不是那么你也不要着急的走可以看完我的文章会对你有所帮助! 首先是 ...
- 【译】Java SE 14 Hotspot 虚拟机垃圾回收调优指南
原文链接:HotSpot Virtual Machine Garbage Collection Tuning Guide,基于Java SE 14. 本文主要包括以下内容: 优化目标与策略(Ergon ...
- the evolution of Lua 全文翻译
终于赶在春节前将论文全文翻译完,以后有时间将前面三章重新翻译一次,因为刚开始的时候没打算全文翻译的..第一次每天花25分钟完成这么长的一篇翻译,证明滴水可以穿石,哈哈哈 中文地址:Lua的演进 祝各位 ...
- GDPR全文翻译(一)
General Data Protection Regulation <一般数据保护法案>全文翻译(一) 编者按 2016年4月14日,欧洲议会投票通过了商讨四年的<一般数据保护法案 ...
- JDK1.8-Java虚拟机运行时数据区域和HotSpot虚拟机的内存模型
目录 介绍 官方文档规定的运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 虚拟机栈和本地方法栈溢出 Java堆 演示堆内存溢出 方法区 运行时常量池 演示方法区溢出 HotSpot虚拟机的内 ...
- HotSpot虚拟机对象相关内容
一.对象的创建 1.类加载检查 普通对象的创建过程:虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化 ...
- HotSpot虚拟机对象探秘-笔记
学习目的:探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程. 1.对象的创建 虚拟机在执行到一条new指令时,先要检查指令的参数(将要实例化的类)是否已经被加载.解析.初始化过,如果 ...
- 深入理解Java虚拟机读书笔记1----Java内存区域与HotSpot虚拟机对象
一 Java内存区域与HotSpot虚拟机对象 1 Java技术体系.JDK.JRE? Java技术体系包括: · Java程序设计语言: · 各种硬件平台上的 ...
- HotSpot虚拟机对象探秘(对象创建,对象内存布局,对象访问定位)
以常用的HotSpot虚拟机和JAVA内存区域堆为例,探讨对象的创建,对象的内存布局以及对象的访问定位 一.对象的创建 1)类加载:虚拟机遇到一条new指令时,先检测这个指令的参数能否在常量池中定位到 ...
- JDK1.7 Update14 HotSpot虚拟机GC收集器
在测试服务器上使用如下命令可以查看当前使用的 GC收集器,当然不止这一个命令可以看到,还有其他一些方式 第三列”=”表示第四列是参数的默认值,而”:=” 表明了参数被用户或者JVM赋值了 [csii@ ...
随机推荐
- Java Set的五种遍历方式
摘要:介绍Java遍历Set的五种方式,并分析哪中方式效率高,建议使用增强for循环变量. Set 和 List 遍历方式基本一致,本文介绍Set的遍历方式,并比较那种方法执行效率最高. 1. ...
- 设置IntelliJ IDEA 2021字体大小
安装Mac版 IntelliJ IDEA 2021.3.1 (Ultimate Edition)后,就需要更改字体.IntelliJ IDEA的字体设置分为两部分:一部分是UI的字体和字号设置,另 ...
- RC4加密解密算法工具类-Java语言实现
摘要 RC4加密解密算法是工具类是大名鼎鼎的 RSA三人组中的头号人物Ron Rivest设计的,可以有效抵御暴力搜索密钥的攻击.鉴于此,提供一个由Java语言实现的工具类. 前言 RC4加密算法 ...
- 【2020.11.25提高组模拟】小 T 与灵石(stone) 题解
[2020.11.25提高组模拟]小 T 与灵石(stone) 题解 题意简述 给一棵根为\(1\)的树.一共\(q\)次操作,每次选\(k_i\)个节点\(p_1,p_2,\dots,p_{k_i} ...
- jenkins的搭建及问题处理
Jenkins搭建第一步 本文讲述的本人搭建Jenkins的流程及遇到的坑及处理方法 1.搭建 Linux操作系统为Centos Jenkins版本为24稳定版 操作命令: sudo wget -O ...
- 蛟分承影,雁落忘归 —— 袋鼠云一站式全自动化运维管家 ChengYing(承影)正式开源
原文地址: 交流蛟分承影,雁落忘归--袋鼠云一站式全自动化运维管家ChengYing(承影)正式开源 技术交流:30537511(钉钉群) 我们兴奋的向大家宣布一个好消息 DTstackCon新成 ...
- About me and the blog
About me and the blog About me 坐标\(CQ\),可以叫我\(Luoyu\)/洛雨/呆猫(似乎混入了奇怪的东西,时常模仿呆猫说话故而得名)/猫老大(???不知道啥时候下一 ...
- 如何用三层防护体系打造坚不可摧的 API 安全堡垒?
扫描二维码 关注或者微信搜一搜:编程智域 前端至全栈交流与成长 发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/ FastAPI 安全与认证综合实 ...
- 8.Java Spring框架源码分析-IOC-调用BeanFactoryPostProcessor的postProcess方法
目录 1. 要研究的代码 2. 处理BeanDefinitionRegistryPostProcessor类型的PostProcessor 2.1. 当前bean工厂是BeanDefinitionRe ...
- 4.分布式事务方案-Saga
1. Saga是什么 保证最终一致性的一种分布式事务方案 2. Saga流程 有多个事务参与者,每个参与者都有两块逻辑:正向操作和逆向操作 把事务分成两个阶段 第一阶段每个参与者执行正向操作 第二阶段 ...