HotSpot C2 的 if 转换代价模型:分支概率与 CMov 的取舍
高吞吐服务里热点分支被 C2 编译成条件传送(CMov)后反而变慢,问题常出在分支概率与代价模型上。文章解释 C2 如何用分支概率决定是否把 if 转成 CMov、CMov 为什么在概率极不平衡时付出额外代价,并给出用 -XX:+PrintIdeal 与反汇编判断分支是否适合 CMov 的方法。
共 7 篇文章
高吞吐服务里热点分支被 C2 编译成条件传送(CMov)后反而变慢,问题常出在分支概率与代价模型上。文章解释 C2 如何用分支概率决定是否把 if 转成 CMov、CMov 为什么在概率极不平衡时付出额外代价,并给出用 -XX:+PrintIdeal 与反汇编判断分支是否适合 CMov 的方法。
为什么 Math.sqrt 和 System.arraycopy 会被 JIT 替换为 CPU 指令?本文聚焦 HotSpot C2 编译器的内在函数机制,解释识别与替换过程、常见内在函数、诊断方法,以及手写代码与内在函数的性能差异,帮助你利用内在函数优化数值计算和数组操作。
本文以接口多实现的高频调用为场景,剖析 HotSpot 内联缓存的单态、多态与巨态状态转换机制,解释多态退化为何损失性能,以及如何通过 -XX:+PrintInlining 观察和避免退化。
高吞吐服务中,热点分支是保留分支指令还是转换为条件传送(CMov)直接决定性能。本文基于 HotSpot C2 编译器的实际实现,剖析 CMov 的收益与代价、C2 如何利用分支概率决定转换,以及 -XX:UseCMov 等参数的影响,帮助读者判断何时该信任 CMov 的优化。
长时间运行的应用中,代码缓存膨胀可能导致 JIT 编译被禁用,性能急剧下降。本文从 nmethod 的生命周期出发,解释 HotSpot 清扫机制的触发条件、分段代码缓存如何缓解碎片化,以及如何通过 -XX:ReservedCodeCacheSize 和 -XX:+UseCodeCacheFlushing 等参数进行监控与调整。
本文解读 JDK 10 引入的线程局部握手机制,说明它如何在不触发全局安全点的前提下对单个线程执行 JIT 去优化、偏向锁撤销等操作,并通过与全局安全点的对比和诊断参数帮助读者理解其适用场景与局限。
本文分析 HotSpot C2 编译器如何根据方法大小、调用频率和调用深度决定内联,解释为何某些热点方法未被内联,并演示如何通过 -XX:MaxInlineSize 等参数优化。以微服务中频繁调用的工具方法为贯穿场景,介绍内联收益与成本、虚方法去虚拟化技术,以及使用 -XX:+PrintInlining 诊断内联失败的方法,帮助读者平衡编译时间与运行时性能。