JVM方法内联效果分析依赖运行时实测、编译日志和性能对比三结合,通过-XX:+PrintInlining确认内联决策,观察常量传播、去虚化等连锁优化,并用JMH量化吞吐量提升10%–40%。

Java 中 JVM 分析方法内联对性能的提升效果,核心不是靠静态推测,而是依赖运行时实测 + 编译日志 + 性能对比三者结合。它不告诉你“理论上快多少”,而是用真实执行数据说明“内联后发生了什么变化、省了哪些指令、触发了哪些连锁优化”。
看 JIT 是否真正执行了内联
加 -XX:+PrintInlining 参数启动程序,JVM 会在控制台输出每一处内联决策:
-
inline (hot) 表示成功内联,后面跟着方法签名和字节码大小,例如
inline (hot) java.lang.String::length (5 bytes) -
did not inline 后跟失败原因,比如
too big(超 325 字节)、not hot enough(调用次数未达 10000 次)、virtual call too complex(虚方法目标不唯一) - 注意:同一方法可能在不同编译层级(C1/C2)中结果不同;C2 输出更关键,因它负责深度优化
观察内联带来的连锁优化效果
内联本身只是第一步,真正的性能跃升来自它解锁的后续优化。可通过以下现象反推内联是否起效:
-
常量传播:如
square(5)被内联后,JIT 直接替换成25,字节码里不再有方法调用指令 -
冗余检查消除:内联后上下文明确,
if (obj == null)被证明永不成立,整段分支被删掉 -
去虚化成功:原本
list.get(i)是接口调用,内联ArrayList.get()后暴露为数组访问elementData[i],跳过动态分派 -
锁消除:局部
StringBuilder被内联+逃逸分析确认未逃逸,synchronized块直接消失
用基准测试验证实际性能差异
仅看日志不够,必须量化效果。推荐用 JMH(Java Microbenchmark Harness)做对照实验:
立即学习“Java免费学习笔记(深入)”;
- 写两组逻辑等价代码:一组用小方法封装(如
add(a, b)),一组手动展开(a + b) - 分别加上 -XX:+PrintInlining 和 -XX:+PrintCompilation,确认前者确实被内联而后者无调用开销可省
- 运行 JMH 测试,关注 ops/s(每秒操作数) 和 ns/op(单次耗时) 的差异
- 典型结果:高频调用的小方法经内联后,吞吐量可提升 10%–40%,尤其在循环体或 getter/setter 密集场景
借助工具定位内联瓶颈
当性能未达预期,需进一步诊断:
-
JITWatch:解析 -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation 生成的
hotspot.log,可视化展示方法调用链、内联层次、失败节点及字节码大小 - hsdis:配合 -XX:+PrintAssembly 查看最终生成的汇编代码,确认调用指令是否真的被移除、是否出现连续的算术指令流
- 重点关注:
@IntrinsicCandidate方法(如System.arraycopy)走的是 intrinsic 优化路径,不走普通内联流程,别误判为“未优化”



















