网站首页 > java教程 正文
前言
执行引擎讲是 JVM 运行原理的最后一个部分。
相对于类加载机制、运行时数据区,这部分没有那么多的知识点,似乎也没见谁说面试问了这个。
所以本文将会比较简要得描述工作流程,个人认为不重要的就不写了。
执行引擎概述
对 JVM 而言,执行引擎就是执行代码的一个软件,所以可以不受硬件环境的约束,执行不被操作系统识别的指令集格式。
JVM 的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被 JVM 所识别的字节码指令、符号表,以及其他辅助信息。
所以,执行引擎的作用就是:将字节码指令 解释 / 编译 为对应平台上的本地机器指令。
简单来说,JVM 中的执行引擎充当了将高级语言翻译为机器语言的译者。
解释器和编译器
Java 既有解释器也有编译器:
- 解释器:当 JVM 启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内 “翻译” 为对应平台的本地机器指令执行。
- JIT 编译器 ( Just In Time Compiler) :就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言。
所以 Java 又成为半编译型半解释型语言。
我们一般说的编译执行,所说的编译都是 javac 前端编译,将 .java 文件编译成 .class 文件。
解释器将根据 PC 寄存器的地址逐行解释执行字节码。
解释器
旧版本的解释执行器是 字节码解释器 ,就是逐条翻译,效率低下。现在已经抛弃。
新版本的是模板解释器,模板解释器将每一条字节码和一个模板函数相关联,模板函数中直接产生这条字节码执行时的机器码,从而很大程度上提高了解释器的性能。
在 HotSpot VM 中,解释器主要由 Interpreter 模块和Code模块构成:
- Interpreter 模块: 实现了解释器的核心功能Powered by Ad.Plus
- Code 模块: 用于管理 HotSpot VM 在运行时生成的本地机器指令
JIT 编译器
当 Hotspot JVM 启动时,顺序应当如下:
- 解释器首先发挥作用,开始解释执行工作;
- 即时编译器逐渐编译字节码,慢慢开始工作;
- 即时编译器探寻热点代码,将有价值的字节码再编译成本地机器指令,以换取更高的执行效率。
热点代码编译
热点代码:一个被多次调用的方法,或者是一个方法体内部循环次数较多的循环体。
因此都可以通过 JIT 编译器编译为本地机器指令。
由于这种编译方式发生在方法的执行过程中,因此也被称之为栈上替换,或简称为OSR (On Stack Replacement)编译。
判定一段代码是否是热点代码,需要依靠热点探测功能,它的工作流程如下:
- 目前 HotSpot VM 所采用的热点探测方式是 基于计数器 的热点探测。
- HotSpot VM 将会为每一个方法都建立2个不同类型的计数器,分别为方法调用计数器(Invocation Counter) 和回边计数器(Back Edge Counter) 。方法调用计数器用于统计方法的调用次数;可以通过 -XX:CompileThreshold 进行设置,server 模式(Java默认模式就是 Server,这个就不管了)下默认值为 10000 次。超过这个阈值就会触发 JIT 编译。回边计数器用于统计循环体执行的循环次数。工作模式和方法调用计数器相同。需要注意的是,它的热点阈值判断需要加上方法调用计数值。
JIT 动态编译判断流程如下:
热度衰减
当然,如果服务一直运行,一段代码肯定会达到阈值进而判定为热点代码,这是迟早的问题。
这显然是不合适的。
所以执行引擎设置了一个热度衰减机制,这个机制参照半衰期来制定:
- 当超过一定的时间限度,方法的调用次数仍然不足以让它提交给即时编译器编译,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减( Counter Decay ),而这段时间就称为此方法统计的半衰周期( Counter Half Life Time )。
- 进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的。
- 可以使用虚拟机参数 -XX:-UseCounterDecay 来关闭热度衰减,让方法计数器统计方法调用的绝对次数,这样,只要系统运行时间足够长,绝大部分方法都会被编译成本地代码。
- 可以使用 -XX:CounterHalfLifeTime 参数设置半衰周期的时间,单位是秒。
这个机制嘛,很好理解,了解下把。。。感觉也用不到。。。
执行引擎参数设置
默认情况下,执行引擎都是采用解释器和编译器并存的模式。当然,可以设置:
- -Xint :完全采用解释器模式执行程序。
- -Xcomp :完全采用即时编译器模式执行程序。如果即时编译出现问题,解释器会介入执行。
- -Xmixed :采用解释器+即时编译器的混合模式共同执行程序。
猜你喜欢
- 2024-09-16 读Java性能权威指南(第2版)笔记08_即时编译器中
- 2024-09-16 Java @SuppressWarnings:抑制编译器警告-4
- 2024-09-16 PHP 8.0正式发布:支持JIT编译器,性能提升高达3倍
- 2024-09-16 「深入理解java虚拟机」(一) - 编译器和字节码文件
- 2024-09-16 学习廖雪峰的JAVA教程---泛型(擦拭法由编译器实现强制转型)
- 2024-09-16 JVM底层原理之如何选用C1、C2编译器?它们有什么区别?
- 2024-09-16 JIT编译器的神奇之处:为什么Java如此快速
- 2024-09-16 JVM底层原理之什么是JIT编译器?什么是HotSpot VM?
- 2024-09-16 C语言/C++/Java 入门到项目 资料和编译器
- 2024-09-16 如何在maven pom.xml文件中设置Java编译器版本
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)