JVM的即时编译器JIT之简单介绍
注:本文源于《深入JAVA虚拟机》一书,提取部分骨干内容,算是读书笔记吧。
本文写于2011年11月
问题:
- 为何JVM需要使用解释器和编译器并存的架构?
- JVM为什么要实现两个不同的即时编译器?
- 程序何时会使用解释器执行?何时会使用编译器执行?
- 哪些程序代码会被编译成为本地代码?如何编译?
- JAVA代码的执行效率就一定比C,C++静态执行的执行差?JAVA代码解析执行有何优势?
序:
从计算机程序出现的第一天起,对效率的追逐就是程序天生的坚定的信仰,这个过程犹如一场没有终点,永不停歇的F1方程式竞赛。
程序员犹如车手,技术平台则是赛道上飞驰的赛车。
JVM即时编译器:即时编译器(Just In Time Compiler) 简称JIT
JAVA程序最初是通过解释器(Interpreter)进行解释执行的,当JVM发现某个方法或代码块运行特别频繁的时候,就会认为这是“热点代码”(Hot Spot Code)。
为了提高热点代码的执行效率,就会将这些“热点代码”编译成与本地机器相关的机器码,进行各个层次的优化。 完成这个任务的编译器就是即时编译器(JIT)。
即时编译器的性能好坏,代码的优化程度高低是衡量一款商用虚拟机优秀与否的最关键指标之一,它是虚拟机最核心最能体现技术水平的部分。
JVM的两款即时编译器JIT
JVM中默认内置了两款即时编译器,称为Client Compiler和Server Compiler。
可以用指定参数的方式,指定采用Client模式和Server模式。默认是mixed模式。
java –Xint 解析 java –Xcomp 编译
为什么解析器与编译器并存:
1、当程序需要迅速启动和执行的时候,解析器首先发挥作用,省去编译的时间,立即执行。随着时间的推移,编译器发挥作用,把越来越多的代码编译成本地代码,获得更高的执行效率。
2、当机器内存限制比较大,可以用解析方式节约内存,反之可以用编译提升效率。
3、解析器还可以作为编译器的“逃生门”。当例如加载了新类后类型结构发生变化,可以采用逆优化,退回到解析状态继续执行。
Client Compiler和Server Compiler
Client Compiler和Server Compiler会实现分层编译(JDK 1.7默认有)。
第0层 程序解析执行,解析器不开启性能监控,可触发第一层编译。
第1层 编译成本地相关代码,进行简单优化
第2层 除编译成本地相关代码外,还进行成编译耗时较长的优化。
Client Compiler获得更高的编译速度 Server Compiler获得更好的编译质量,无须承担性能监控的任务
热点代码
两类:1、多次被调用的方法
2、多次被执行的循环体
热点判定方式,两种:
1、基于采样的方式探测(Sample Based Hot Spot Detection) 。周期性检测各个线程的栈顶,发现某个方法经常出险在栈顶,就认为是热点方法。好处就是简单,缺点就是无法精确确认一个方法的热度。容易受线程阻塞或别的原因干扰热点探测。
2、基于计数器的热点探测(Counter Based Hot Spot Detection)。某个方法超过阀值就认为是热点方法,触发JIT编译。(涉及计数器的热度半衰减过程)
两个计数器:方法调用计数器(Invocation Counter)和回边计数器(Back Edge Counter)
触发了JIT编译,编译工作完成,这个方法的入口就会被系统自动改为新的编译入口,就会调用编译的版本。
JVM编译优化技术-----逃逸分析
JDK设计团队,几乎把所有的优化措施都集中在即时编译器中。一般认为,编译器的本地会比javac的产生的字节码更优秀。
常见的优化技术很多:例如公共表达式的消除,数组边界检查的消除,方法的内联(最重要的优化技术)
介绍一个JVM最前沿的优化技术:逃逸分析:
逃逸分析:当一个对象被定义后,可能被外部方法引用,例如被当作参数传递到其他方法中,称为方法逃逸。可以被其他线程访问,这个称为线程逃逸。
若能证明这个对象不会逃逸到其他方法或线程中,就可以进行高效的优化。
1、栈上分配 在堆上分配对象内存,回收整理内存需要消耗时间,若在栈上分配内存将是个不错的主意。被对象占用的空间就可以随帧栈的就出栈而销毁。大量的对象随方法的结束而自动销毁,GC也减轻压力。
2、同步消除 若不会线程逃逸,不会有竞争,方法上的同步措施就会消除。
3、标量替换 JAVA的原始类型无法再分就是一个标量,对象就是聚合量。对象若可以被拆分成标量,直接在栈上分配,就是类似栈上分配内存,甚至分配到高速缓存中。
逃逸分析不成熟的原因:不能保证逃逸分析的性能收益大于它的消耗。
Java与C/C++编译器对比
Java与C/C++编译器的对比,代表了最经典的即时编译器与静态编译器的对比。除了自身API的实现的好坏,更多是一场“拼编译器”和“拼输出代码质量”的游戏。
看看这两种语言的编译器的优劣:
1、即时编译器运行占用的是用户的运行时间,具有很大的时间压力,它提供的优化手段严重受制与编译的成本。而编译的时间在静态编译中并不是主要关注点。
2、java语言是动态的类型安全语言,意味着由虚拟机确保程序不会违反语言的语义或访问非结构化内存。虚拟机需要频繁的动态检查,如空指针,数组越界,继承关系等,总体消耗不少时间。
3、java语言使用虚方法的频率远大于C/C++,意味对方法的接收者进行多态的选择频率远大于C/C++,意味着即时编译器的优化难度远远大于C/C++编译器。
4、java语言是动态扩展的语言,运行时会加载新的类,改变程序的继承关系,使得很多全局优化难以进行。只能采用激进的方式,在运行时撤销或重新进行一些优化。
5、java语言的对象是在堆上分配,只有方法的局部变量才在栈上分配。而C/C++语言有多种分配方式,既可以在堆上分配,又可以在栈上分配,减轻了内存回收的压力。另外C/C++语言主要由用户代码回收内存,不存在无用对象筛选的过程,效率要比垃圾回收机制要高。
但是:
Java语言在性能上的劣势都是为了换取开发效率上的优势而付出的代价。动态安全,动态扩展,垃圾回收这些“拖后腿”的特性都是为JAVA的开发效率做出了很大的贡献。
何况java即时编译器能做的,C/C++的静态优化编译器不一定能够做:
由于C/C++的静态编译,以运行性能监控为基础的优化措施它都无法进行,如调用频率预测,分支频率预测,裁剪未使用分支等,这些都是称为java语言独有的性能优势。
相关推荐
21丨深入JVM即时编译器JIT,优化Java编译.html
Java即时编译器(JIT,Just-In-Time Compiler)是Java虚拟机(JVM)的重要组成部分,它在程序运行期间对热点代码进行编译,从而提高程序的运行效率。前端编译是指将.java源文件编译成.class字节码文件的过程,而JIT...
JIT编译器是Java性能优化的关键,它通过将字节码转换为本地机器码并进行优化,显著提高了Java程序的执行效率。通过理解JIT编译器的工作原理和优化技术,开发者可以更好地编写高效的Java代码。JIT编译器的存在使得...
JVM不仅提供了平台无关的运行环境,还内置了一个高效的即时编译器(JIT)。本文将详细介绍Java JIT编译器的工作原理、优化策略以及如何在实际开发中利用JIT提高程序性能。 Java JIT编译器是提高Java程序性能的关键...
JIT(Just In Time)编译器是一种即时编译技术,它可以加速Java程序的执行速度。 JIT编译过程 -------- 在执行Java程序时,JVM会将字节码编译成本机机器码,并进行多层次的优化。这个过程可以分为两个阶段:解释...
JIT编译器有三个关键阶段:解释器、即时编译和优化。在程序启动初期,JVM使用解释器执行字节码,随着代码执行次数增加,JIT会将热点代码编译成本地机器码,实现更快的执行速度。 2. JIT编译策略 JIT编译器采用两种...
Java虚拟机(JVM)即时编译器(JIT)是Java平台的一个重要组成部分,它在运行Java程序时提供优化以提高性能。即时编译器通过监控Java程序的执行行为,对运行最频繁的方法进行编译,将字节码转换为本地机器代码,从而...
然而,现代JVM采用了一种称为即时编译(JIT,Just-in-Time compilation)的技术来提升性能。JIT编译器是JRE的一部分,它会在程序运行时动态地将热点代码(经常执行的代码块)编译成原生机器码。这种方式在保持灵活性...
在Java的HotSpot虚拟机中,即时编译器(JIT,Just-In-Time Compiler)扮演着关键角色,它负责将字节码转换为机器码以提高程序的运行效率。HotSpot包含两种即时编译器:客户端编译器(C1)和服务器端编译器(C2)。C1...
避免使用Java序列化14讲多线程之锁优化(下):使用乐观锁优化并行操作16讲多线程调优(下):如何优化多线程上下文切换17讲并发容器的使用:识别不同场景下最优容器21讲深入JVM即时编译器JIT,优化Java编译25讲答疑...
为了解决这一问题,Java虚拟机(JVM)引入了即时编译器(JIT),这是一种能够在程序运行过程中动态地将字节码编译成本地机器码的技术,从而极大地提升了Java程序的性能。 ##### JIT编译器的工作原理 1. **解释执行...
《用代码缓存复用技术提升Android即时编译器效率》这篇论文主要探讨了如何在资源有限的嵌入式平台上,尤其是Android系统中,通过优化即时编译技术来提高Java虚拟机(JVM)的执行效率。即时编译(Just-In-Time, JIT)...
本教程详细介绍了JVM(Java虚拟机)的结构、类型和编译器模式、参数分类、即时编译器(JIT)诊断工具、垃圾回收机制、内存调优方法,以及并行和CMS垃圾回收器的优化策略。重点内容包括: JVM类型和编译器模式:...
3. **JIT编译器**:为了进一步提高性能,Dalvik引入了即时编译器(Just-In-Time Compiler, JIT),可以在运行时将字节码编译成本地机器代码。 #### 三、Dalvik JIT编译器原理 在Android 2.2版本中引入了JIT编译器来...
4. 执行引擎:解释器负责逐条解释执行字节码,而即时编译器(JIT)会将热点代码编译成本地机器码,以提高运行效率。 5. 内存管理:JVM的垃圾回收机制自动管理内存,包括对象的分配和回收。常见的垃圾收集算法有标记...
5. **编译优化**:JVM的即时编译器(JIT)将热点代码编译为本地机器码,提高执行效率。了解并优化HotSpot的编译策略(例如,方法的进入次数阈值)可进一步提升性能。 6. **监控与诊断工具**:如VisualVM、JProfiler...
- **JIT定义**:Just-In-Time Compiler,即时编译器,能够在运行时将字节码编译成本地机器码。 - **作用**:提高程序执行效率,尤其是对于频繁执行的代码片段。 - **功能**:识别“热点代码”,即执行频率高的代码,...
8. **JIT编译器**:介绍JVM的即时编译器(Just-In-Time Compiler),它将热点代码编译为机器码以提高执行效率。 9. **内存泄漏与性能瓶颈**:识别和解决内存泄漏问题,以及如何定位和解决性能瓶颈。 10. **实战...
这些指令是给JVM解释器或者即时编译器(JIT)使用的低级指令集。在JVM上运行的Java程序会被编译成一系列指令,然后由JVM执行。 从给定文件的【部分内容】可以提炼出以下知识点: 1. JVM指令类型:JVM指令可以分为...
在周鹤洋于RustChinaConf2020上的演讲《用Rust设计高性能JIT执行引擎》中,他探讨了如何使用Rust这一编程语言来构建高效且安全的即时编译器(JIT)。Rust以其强大的内存安全特性和系统级编程能力,成为构建这种复杂...