分层编译是JVM按热度动态升级执行层级的机制:0层解释执行→1–3层C1轻量编译(无/有限/完整profiling)→4层C2深度优化,C1保启动快,C2求峰值高,五级闭环协作,JDK 8起默认启用。

分层编译不是让 C1 和 C2 轮流上场,而是让它们按需协作、逐级升温——方法从解释执行起步,随着热度上升,自动“晋级”到更高级别的编译层级。
C1 先扛住启动压力,不求极致,但求快
C1 编译器不做复杂分析,跳过耗时的运行时类型推断、激进内联或逃逸分析。它用轻量级优化(如常量传播、简单方法内联)快速生成可执行代码,把方法从解释执行(level 0)推进到编译执行(level 1–3),大幅缩短冷启动延迟。
- level 1:C1 编译,无 profiling,适合结构简单、调用频繁但行为稳定的方法
- level 2:C1 编译 + 基础热点统计(方法调用次数、循环回边次数),平衡速度与信息收集
- level 3:C1 编译 + 完整 profiling(分支走向、虚方法接收者类型等),为 C2 提供高质量决策依据
C2 在后台静默准备,只对真正热门的方法出手
C2 不会一上来就编译所有方法,它依赖 C1 阶段积累的 profiling 数据判断哪些方法值得深度优化。只有当方法被反复执行、分支模式稳定、对象逃逸路径清晰时,C2 才介入生成高度优化的本地代码(level 4)。
- 它启用标量替换、循环向量化、去虚拟化、冗余检查消除等重量级优化
- 编译耗时明显长于 C1,但生成代码的长期吞吐和指令效率显著更高
- 若 C2 线程繁忙,JVM 可能暂缓升级,让 C1 维持 level 2 或 3 运行,避免卡顿
五级执行层级构成动态反馈闭环
HotSpot 把执行划分为 0–4 五个层级,不是单向递进,而是根据运行时反馈动态调整:
- 解释器(level 0)持续监控方法执行频次和循环回边,触发首次 C1 编译
- C1 编译后继续插桩收集 profile,一旦数据达标,提交给 C2 队列
- 若某方法在 C1 下已足够快(比如纯计算且无分支),可能永远不升到 level 4
- 反向降级也存在:C2 编译后的代码若遇到类重定义或去优化条件(如类型假设失败),会退回到解释执行重新积累 profile
默认开启,多数场景无需干预
自 JDK 7 起,-XX:+TieredCompilation 已默认启用;JDK 8 及以后版本甚至不再支持关闭分层编译。现代应用(Spring Boot、微服务等)天然适配该模型:既避免传统 C1 模式下的峰值性能瓶颈,也规避纯 C2 模式下漫长的预热期。
除非明确压测中发现编译线程争抢严重(如 CPU 密集型批处理),一般不需要调优 C1/C2 线程数或强制指定编译器。JVM 会按 CPU 核心数自动配置 1:2 的 C1:C2 编译线程比例,并动态调度任务优先级。

















