即时编译回顾
HotSpot 虚拟机执行 Java 程序时,先通过解释器对代码解释执行,发现某个方法或代码块执行比较频繁后,对热点代码进行编译,编译后生成与本地平台相关的机器码,再去执行机器码获得较高的运行效率。必要时,也会通过逆优化从即时编译回到解释执行,如编译器遇到罕见陷阱的情况。
在 Java 虚拟机规范中,并未要求虚拟机必须实现即时编译,但即时编译在主流的虚拟机中都有实现,后文所有讨论都基于 HotSpot 虚拟机。
即时编译器
HotSpot 虚拟机中有两个即时编译器,分别为 Client Compiler 和 Server Compiler,简称为 C1 编译器和 C2 编译器。C1 编译器占用内存小,进行局部优化,代码执行效率比 C2 编译器低,适用于客户端应用; C2 编译器占用内存大,进行全局优化,代码执行效率比 C1 编译器高,适用于服务端应用。在 JDK 1.7 以后的 HotSpot 虚拟机中,采用了被称为分层编译的策略,启动时解释执行提高启动速度,然后 C1 编译获取较好的编译速度,再 C2 编译获取较好的编译质量。
默认情况下,虚拟机会自动选择合适的编译器与解释器一起配合工作,用户也可以在启动参数里使用 “-client” 或 “-server” 来强制要求虚拟机使用某一种编译器。编译器与解释器一起配合工作的模式,被称为混合模式。用户也可以在启动参数里使用 “-Xint” 来要求虚拟机只使用解释器,使用 “-Xcomp” 来要求虚拟机只使用编译器。
被多次调用的方法和被多次执行的循环体,就是即时编译器关注的热点代码。在 HotSpot 中,采用了基于计数器的热点探测技术,为每个方法定义了两个计数器:方法调用计数器、回边计数器。
默认情况下,如果一段时间内方法调用计数器的值没有超过虚拟机设置的阈值,则在垃圾回收时计数器会热度衰减,数值减少 1/2,此时间范围又被称为半衰期。所以方法调用计数器中存储的实际上并不是方法调用的绝对次数。用户可以调整半衰期的值,甚至可以关闭热度衰减。
回边计数器则统计了循环体执行的绝对次数,它的阈值可以由方法调用计数器的阈值计算出来。如果回边计数器发生溢出,也会把方法调用计数器调整为溢出。
调用方法时,如果两个计数器之和超过了方法调用计数器的阈值,就会提交方法的编译请求。循环体执行时,如果两个计数器之和超过了回边计数器的阈值,也是编译代码块所在的方法,因为此时方法正在执行中,又被称为栈上替换,即替换方法时方法的栈帧还在栈上。
默认情况下,编译器在后台进行编译,即调用热点代码发现需要编译时,先以解释方式继续执行,向编译器发送编译请求,编译结束后下次调用时才使用编译的本地代码。用户也可以通过启动参数来要求虚拟机禁止后台编译,编译结束前热点代码的执行处于阻塞状态。
优化技术
HotSpot 虚拟机使用了很多种优化技术,这里只简单介绍其中的几种,完整的优化技术介绍可以参考官网内容。
公共子表达式消除:
如果一个表达式已经进行过计算,并且在下次用到之前依赖的变量没有变化,即表达式的计算结果不会发生变化,则在下次使用这个表达式时直接使用计算的结果。
数组边界检查消除:
在 Java 中访问数组时,会自动进行边界检查来防止数组下标越界。但是对于某些情况并不需要每次访问都去检查,如在一个循环中遍历数组元素,如果虚拟机能够确定下标不会发生越界并且优化确实能够提高运行速度,则虚拟机会去除每次访问的下标检查。
方法内联:
对于可以内联的方法,直接复制到调用者代码中,减少方法调用次数和性能消耗。
逃逸分析:
方法中定义的一个对象,如果会被其他方法访问则称为方法逃逸,如果会被其他线程访问则称为线程逃逸。对于不能逃逸的对象,HotSpot 虚拟机采用了栈上分配、同步消除、标量替换等方法进行优化。
每周 3 篇学习笔记或技术总结,面向有一定基础的 Java 程序员,内容涉及 Java 进阶、虚拟机、MySQL、NoSQL、分布式计算、开源框架等多个领域。关注作者或微信公众号 backend-develop 第一时间获取最新内容。
相关推荐
Dalvik虚拟机,作为Android早期的核心组件,引入了即时编译(Just In Time, JIT)技术,显著提升了应用程序的运行效率。本文旨在深入探讨Dalvik虚拟机中JIT技术的实现原理,以及其在Android平台上的应用。 #### ...
研究如何降低字节码编译的不利影响和提高编译质量是嵌入式JIT技术研究的主要问题。部分编译字节码、基于概率的编译、 profile-guided 编译等方法都是当前研究的热点。 本文提出的改进的即时编译器代码选择策略和...
wwwwwwwwwwwwwwwwww
JIT(Just In Time)编译器是一种即时编译技术,它可以加速Java程序的执行速度。 JIT编译过程 -------- 在执行Java程序时,JVM会将字节码编译成本机机器码,并进行多层次的优化。这个过程可以分为两个阶段:解释...
它通过即时(Just-In-Time, JIT)编译技术将源代码直接转化为机器码,这一特性使得Euboea在运行时能够获得接近原生代码的性能。JIT编译是一种动态编译技术,它在程序运行时对部分或全部源代码进行编译,而非在程序...
NativeJIT是一个开源项目,旨在提供一个跨平台的高性能即时编译(JIT)库,特别关注于C++中的数学表达式和数据结构的优化编译。这个库允许开发者将数学表达式直接编译为机器码,从而在运行时实现快速计算,尤其适用...
CLR只执行本机的机器代码。有两种方式产生本机的机器代码:实时编译和预编译方式。...只有当要调用某个方法时,JIT编译器才会将CIL的方法体编译为相应的本机机 器码版本。这样可以优化程序的工作集。
关于C#编译原理,高级教程之一的指导教程。
### JIT配送管理浅析 #### 一、JIT配送概述 **JIT配送**,即“Just in Time”(准时制)配送,是一种高效的物流管理方法。它强调在客户规定的精确时间,将所需产品准确地送达指定地点。这种方式通常采用小批量、多...
Java即时编译器(JIT,Just-In-Time Compiler)是Java虚拟机(JVM)的重要组成部分,它在程序运行期间对热点代码进行编译,从而提高程序的运行效率。前端编译是指将.java源文件编译成.class字节码文件的过程,而JIT...
本文主要介绍了Java编译技术的几种类型,包括解释器、静态编译器、即时编译(JIT)技术和动态编译,以及它们各自的特点和优缺点。 首先,Java编译系统大致可以分为五类:使用解释器的系统、使用即时编译技术的系统...
一个速度奇快的 JSON 序列化/反序列化库,由 JIT (即时编译)和 SIMD (单指令流多数据流)加速。运行时对象绑定,无需代码生成。完备的 JSON 操作 API。对于所有大小的 json 和所有使用场景, Sonic 表现均为最佳...
课件中可能还会涉及一些特定的主题,例如编译器设计原则、编译器构造工具(如ANTLR、Flex和Bison)、运行时系统、JIT(Just-In-Time)编译以及现代编译技术的最新发展,比如LLVM框架。 通过《钱焕延编译技术(第二...
实现Vue SSR即时编译技术的项目可以在GitHub上找到,例如vue-ssr-jit项目,该项目提供了相关文档和代码实现,可供进一步学习和研究。需要强调的是,在使用npm安装时,需要使用命令行指定版本。 通过上述知识点的...
Java作为一门广泛使用的编程语言,其虚拟机(JVM)的即时编译(JIT)机制是提升应用程序运行效率的关键技术之一。即时编译不同于传统的静态编译,它在程序运行时才将字节码转换为机器码,这样既可以保持Java的跨平台...
即时编译喷射是一种技术,通过利用ActionScript即时编译器(JIT Compiler)的行为来将shellcode写入可执行内存,从而绕过DEP的限制。DEP旨在阻止非执行区域的代码执行,而JIT Spraying利用了JIT编译器在特定条件下将...
Java虚拟机(JVM)中的Just-In-Time (JIT)编译是提高性能的关键技术之一。JIT编译器能够将字节码转换成本地机器代码,以便更快地执行。这里我们将详细探讨JIT编译以及执行本地代码的流程,特别关注标题和描述中提到的...
编译技术不仅用于传统意义上的编程语言翻译,还广泛应用于JIT(Just-In-Time)编译、动态语言实现、代码分析和优化等领域。 6. **现代编译技术**: 现代编译技术包括并行化、GPU编程支持、泛型编程、类型推断等,...