OpenJDK怎么判断哪些代码是热点代码

胖辰小哥_6795

胖辰小哥_6795

2026-10-31

168人浏览

原创

HotSpot 通过方法调用计数器和回边计数器精确识别热点代码:前者统计方法调用次数,后者统计循环回跳次数;任一达到阈值即触发JIT编译,OSR编译仅依赖回边计数器。

openjdk怎么判断哪些代码是热点代码

HotSpot 用两个计数器判断热点代码

OpenJDK(确切说是 HotSpot VM)不靠采样,而是通过精确计数来识别热点代码。它维护两个独立的计数器:方法调用计数器和回边计数器。前者统计方法被调用的次数,后者统计循环体(如 for、while)执行“回跳”到循环头的次数——也就是循环迭代次数。只有当任一计数器达到阈值,对应的方法才会被标记为热点,触发 JIT 编译。

-XX:CompileThreshold 参数影响实际触发点

默认阈值不是固定不变的,它取决于 JVM 启动模式:

  • Server 模式(64 位常见,默认):方法调用计数器阈值是 10000,回边计数器也是 10000
  • Client 模式(已基本弃用):两者默认都是 1500
  • 可通过 JVM 参数显式调整,例如:-XX:CompileThreshold=5000会同时降低两个计数器的触发门槛
  • 注意:-XX:+TieredStopAtLevel=1 等分层编译控制参数会影响计数器是否启用或如何累积,不能只看单个参数

方法未内联时,计数器行为容易被误判

如果一个高频调用的方法被 JIT 决定内联(inline),它的字节码就不再以独立方法形式存在,方法调用计数器也就不会为其单独累加——此时“热点”会转移到调用方方法上。这意味着:

财经热点新闻爬取与话题归纳系统
财经热点新闻爬取与话题归纳系统

抓取主流财经网站实时热点,提供混合评分与专业HTML报告,支持快讯采集和话题归纳。

下载
  • 你看到的 javap -c 输出里没被内联的方法,才可能有独立的调用计数
  • 用 -XX:+PrintCompilation 观察日志时,若某方法长期不出现,未必不热,可能是已被内联进父方法了
  • -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining 可验证内联决策,比单纯盯计数器更可靠

OSR 编译只依赖回边计数器,且发生在方法执行中

当一个长循环在解释执行中反复跳转(比如一个跑了几万次的 while(true)),即使该方法本身调用次数很少,只要回边计数器达标,JIT 就会启动 OSR(On-Stack Replacement)编译——即在栈上把正在运行的解释版本替换成编译后的本地代码。这说明:

  • OSR 不需要方法“完整执行完一次”,它针对的是正在运行中的循环体
  • 这类热点无法通过简单统计“方法调用频次”发现,必须关注循环内部的回边行为
  • 高 CPU 占用但方法调用不多的场景(如事件循环、游戏主循环),往往就是 OSR 的典型用武之地

真正难把握的不是“怎么查计数器”,而是理解计数器背后的行为前提:内联策略、分层编译层级、解释器预热延迟、甚至 GC 停顿都可能让计数器暂停或重置。别只盯着 -XX:CompileThreshold 调数字,先用 -XX:+PrintCompilation 和 -XX:+PrintInlining 看清实际发生了什么。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

60

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

40

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

120

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

140

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

120

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

80

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

40

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

80

25

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

2026.10.22

40

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
OpenJDK项目Wiki
OpenJDK项目Wiki

共0课时 | 0人学习

OpenJDK构建指南
OpenJDK构建指南

共0课时 | 0人学习

OpenJDK官网文档
OpenJDK官网文档

共0课时 | 0人学习