怎么利用 Java Mission Control (JMC) 深度剖析生产环境中的线程锁竞争瓶颈

千墨君_2910

千墨君_2910

2026-04-15

208人浏览

原创

Contended Locks表为空是因为JVM未启用锁采样:需确保启动时加-XX:+FlightRecorder、JMC中Start Recording并勾选Lock Profiling,且ReentrantLock非公平模式不触发JVM级锁膨胀,故不会出现在该视图中。

怎么利用 java mission control (jmc) 深度剖析生产环境中的线程锁竞争瓶颈

直接看 JMC 里的 Contended Locks 视图,但前提是 Flight Recorder 必须启用锁采样 —— 否则你看到的全是空表或零星数据。

为什么 Contended Locks 表里没数据?

不是 JMC 不行,是 JVM 没给你录。默认启动的 JFR 不采集锁竞争事件,必须显式开启:Lock Profiling。

  • 启动时漏加 -XX:+FlightRecorder:老版本 JDK(如 8u20)或容器镜像常默认关闭,JMC 连不上或连上后无事件
  • 连接后没点 Start Recording → 勾选 Lock Profiling:JMC 默认只开基础事件,Contended Locks 属于“按需启用”项,不手动勾就等于没开
  • 用了 ReentrantLock 非公平模式:它走 AQS + CAS,不触发 JVM monitor 膨胀,Contended Locks 列表天然不显示 —— 这时候别死磕视图,转去 Events 页搜 jdk.JavaMonitorEnter 或用 jstack -l 查 parking to wait for

怎么从 Contended Count 定位到具体业务代码?

光看「争抢次数高」没用,得关联到实例和调用栈。JMC 不自动帮你跳转,要手动钻取。

  • 在 Lock Instances 视图中,按 Contended Count 倒序,找前几条:重点关注 java.lang.Object、java.util.HashMap 或你自定义的锁对象(如 OrderService$LockHolder)
  • 右键目标锁实例 → Show Stack Trace:不要只看最顶上几行(比如 synchronized 方法入口),往上翻,找到第一个 at com.yourpackage. 开头的类和方法,那才是业务逻辑入口
  • 注意锁对象地址(如 @7f8a1c2b)是否重复出现在多个线程堆栈里:如果是,说明是同一个实例被争抢;如果每个线程都卡在不同地址的 java.lang.Object@xxx,大概率是对象锁粒度太细或误判

线上开 JFR 锁分析会不会拖慢服务?

会,但可控。关键不在“开不开”,而在“怎么开”。

java-api-doc-generator
java-api-doc-generator

分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。

下载
  • 禁用高开销事件:比如关掉 jdk.ObjectAllocationInNewTLAB(对象分配采样),它对吞吐影响最大
  • 用 --settings=profile 而非 default:前者已做过权衡,锁相关事件保留,其他冗余项精简
  • 限制时长:用 duration=30s 或 jcmd JFR.start duration=30s,短时抓取比长时录制更安全
  • 避开流量高峰:锁竞争往往在峰值前后 1–2 分钟最明显,不必 24 小时开着 —— 等现象复现再触发一次即可

Contended Locks 数据延迟严重,怎么抓瞬时尖峰?

JMC 的锁聚合是周期性的(通常 10–20 秒),短于这个窗口的竞争事件会被合并或丢弃。

  • 单次录制时间不能低于 20 秒,否则可能错过聚合周期 —— 建议设为 duration=60s,确保至少覆盖 3 个聚合窗口
  • 如果已知尖峰发生在某秒级区间(比如支付回调集中触发),优先用 jstack -l 抓快照:它不依赖 JFR,毫秒级定格,搜索 BLOCKED on 或 waiting to lock 更直接
  • 对高频小竞争(如每秒上千次 synchronized 块),JMC 可能只记下“总次数”,丢失分布细节 —— 这时候得靠代码埋点,比如在锁入口打日志:log.debug("lock enter, queueLen={}", lock.getQueueLength())

真实瓶颈往往藏在“看起来合理”的锁里:比如一个 static final Object 被五个服务共用,或者 ConcurrentHashMap 的某个桶被热点 key 锁死。JMC 给的是线索,不是结论 —— Contended Count 高只是起点,真正要盯住的是那个反复出现在堆栈顶部的业务类名。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

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

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

下载

相关标签:

java

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

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11597

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8702

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7472

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1224

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

988

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1476

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

3049

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20291

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1335

8

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习