jvm之执行引擎
一、字节码执行流程
Java 源码 → javac 编译 → Class 字节码 → JVM 执行引擎运行
执行引擎两种模式:解释执行 + 编译执行
1. 解释执行
- JVM 自带解释器,逐行读取字节码、边解释边执行
- 启动快、无需预热
- 缺点:循环 / 高频代码反复解释,执行效率低
2. 编译执行(JIT)
- 运行时探测热点代码,一次性编译为本地机器码
- 直接交由 CPU 执行,效率极高
- 启动慢、占用额外 CPU / 内存做编译优化
3. 结合模式(现在 JDK 默认)
解释器兜底 + JIT 编译器提速
启动先用解释器快速跑,热点代码触发 JIT 编译,兼顾启动速度与运行性能。
二、JIT 即时编译
1. 两大编译器
C1 编译器(客户端编译器)
- 简称:轻量编译器
- 特点:编译速度快、简单优化、低耗时
- 适用:桌面程序、对启动速度敏感场景
C2 编译器(服务端编译器)
- 简称:高质量编译器
- 特点:编译慢、深度复杂优化、极致运行性能
- 适用:服务端、长运行、高并发项目
2. 分层编译(JDK8 默认开启)
分为多层,核心逻辑:
- 0 层:纯解释执行
- 1 层:C1 简单编译,快速优化
- 2/3 层:C1 收集完整性能统计数据
- 4 层:C2 深度优化编译
优势:
前期 C1 快速编译、不卡顿;后期热点代码交给 C2 极致优化。
3. 热点代码探测
判定两类代码为热点,触发 JIT 编译:
多次调用的方法
多次循环的循环体
通过计数器统计:
方法调用计数器
回边计数器(循环)
阈值达标,触发即时编译。
三、JVM 三大经典优化
1. 逃逸分析
核心:分析对象作用域
判断一个对象:是否会逃出当前方法 / 线程
- 不逃逸:对象只在当前方法内使用
- 方法逃逸:对象传出方法外部
- 线程逃逸:对象被多线程共享
逃逸分析是后续所有优化的前提。
2. 栈上分配
- 普通对象:默认分配在堆,需要 GC 回收
- 未逃逸对象:直接分配在虚拟机栈
- 方法执行结束,栈帧销毁,对象自动释放
- 完全省去 GC 开销
3. 标量替换
- 标量:无法再拆分的数据(基本数据类型)
- 聚合量:对象(可拆分)
- JVM 把未逃逸对象拆解为多个基本变量
- 不创建连续对象内存,只在栈 / 寄存器存零散变量
- 进一步减少内存占用、提升速度
jvm之执行引擎
http://hanqichuan.com/2026/04/17/jvm/JVM之执行引擎/