【Java】性能调优:利用 jstack 寻找 Java 程序卡顿的真相

article/2025/6/9 6:06:00

前言

当 Java 程序出现给人感觉 “卡顿”、“响应慢”、CPU 风调高、系统给予调用总是延迟时,我们需要采用系统层和虚拟机层的合理工具来分析细节。

本文仅从 JVM 的角度来分析,研究如何利用 jstack 进行 Java 程序性能调优。

Java 程序卡顿的常规原因

  1. 线程互换使用不对:

    • 长期卡在 synchronized / ReentrantLock

    • 正处于等待 wait/notify 或者 park/unpark

  2. 线程正处于终端循环,而输入不足。

  3. 线程正处于 I/O 阻塞

    • 如 MySQL 耗时很长

    • Redis 带宽不足

  4. 全局 GC 分时过长,使程序队列拥塑扩大

  5. 正处于微事务阻塞,这在大数据场景中很常见

jstack 能给我们什么?

stack 是 JVM 内部线程状态的环境抽样工具,它能读取正在运行进程所有线程的 call stack。

它可以用于分析:

  • 当前每个线程在做什么

  • 是否有线程太多卡在同一个场景

  • 是否有死锁 / 响应等待

jstack 输出与卡顿分析的对应

jstack 信息分析意义
java.lang.Thread.State: RUNNABLECPU 正在执行的东西
WAITING / TIMED_WAITING线程等待事件,可能卡在锁或等待结果
waiting to lock <0x…>同步类锁,可能有互换错误
locked <0x…>当前线程所拥有的锁
at xxx.yyy.zzz线程标记的当前校验或执行位置

jstack 分析重点指标

  1. 各类线程状态的分布量

     确定是否有大量 WAITING / BLOCKED
    
  2. RUNNABLE 状态中最顶部的几个方法进入频率

     确定是否有 CPU 热点问题
    
  3. waiting to lock 和 locked 的处理

     分析有时是同一个对象导致的失效交互
    
  4. 出现频率指标分析:连续 3 次出现同样的场景即同步热点

重点指标对应检测方法

  1. 各类线程状态的分布量
# grep 线程状态分布
cat dump.jstack.log | grep "java.lang.Thread.State" | sort | uniq -c
  1. 锁卡顿情况
# grep 锁的卡顿情况
cat dump.jstack.log | grep "waiting to lock" | sort | uniq -c | sort -nr
  1. 线程总数
# 线程总数
cat dump.jstack.log | grep '^"' | wc -l

实用脚本

基于以上内容,我让大模型帮我写了一个脚本,能够很方便的得到分析结果

jstack_analyzer.sh

#!/bin/bashPID=$1
LOOPS=${2:-3}
INTERVAL=${3:-5}if [ -z "$PID" ]; thenecho "用法: $0 <pid> [循环次数=3] [间隔秒数=5]"exit 1
fiecho "分析进程 PID: $PID"
echo "采样次数: $LOOPS, 间隔秒数: $INTERVAL"
echo ""SNAPSHOTS=()
TOP_METHOD_FILES=()# ============ 采样并记录 =============
for i in $(seq 1 $LOOPS); doTS=$(date +%Y%m%d-%H%M%S)FILE="jstack_${PID}_$TS.txt"jstack "$PID" > "$FILE"echo "📸 第 $i 次采样: $FILE"SNAPSHOTS+=("$FILE")# 提取 RUNNABLE 栈顶方法,记录到临时文件TOPFILE="runnable_top_${i}.txt"awk '/java.lang.Thread.State: RUNNABLE/,/^$/' "$FILE" \| grep "^ *at " | head -1 | sed 's/^ *//' >> "$TOPFILE"TOP_METHOD_FILES+=("$TOPFILE")if [ $i -lt $LOOPS ]; thensleep "$INTERVAL"fi
done# ============ 常规指标:最后一次快照分析 =============
echo
echo "======================================="
echo "🧭 使用最后一次快照 ${SNAPSHOTS[-1]} 做常规分析"
echo "======================================="analyze_snapshot() {local FILE=$1echo "------------ [线程状态统计] ------------"grep "java.lang.Thread.State" "$FILE" | sort | uniq -c | sort -nrechoecho "------------ [RUNNABLE 线程热点栈顶] ------------"awk '/java.lang.Thread.State: RUNNABLE/,/^$/' "$FILE" | grep "at " | sort | uniq -c | sort -nr | head -15echoecho "------------ [锁等待情况 waiting to lock] ------------"grep "waiting to lock" "$FILE" | sort | uniq -c | sort -nr | head -10echoecho "------------ [线程总数] ------------"grep -c '^"' "$FILE"echo
}analyze_snapshot "${SNAPSHOTS[-1]}"# ============ 差异化分析:RUNNABLE 栈顶热点交集 ============
echo
echo "======================================="
echo "🔥 持续热点方法分析(${LOOPS} 次采样中都出现)"
echo "======================================="# 合并所有栈顶方法,统计频率
cat "${TOP_METHOD_FILES[@]}" | sort | uniq -c | sort -nr > merged_top.txt# 打印出现 >= 所有轮次 的方法(持续热点)
awk -v threshold="$LOOPS" '$1 >= threshold {print $1, $2, $3, $4, "..."}' merged_top.txt# 可选:清理中间文件
# rm -f runnable_top_*.txt merged_top.txt

使用方法:

chmod u+x jstack_analyzer.sh
./jstack_analyzer.sh 5 10

输出结果:
在这里插入图片描述
通过这个结果再结合top来分析(我这是一个正常的程序,没有卡顿)通过top来看负载不高,cpu占用率不高。
于是可以得到结论:
大量 WAITING + 低负载(low CPU) = 当前进程大概率“处于空闲/低活动状态”,这通常是正常的。

等有时间我将会再举出几个卡顿的例子,如由于IO引起的卡顿,由于线程池满引起的卡顿,由于锁竞争引起的卡顿。未完待续~


http://www.hkcw.cn/article/VqdXmxZIiE.shtml

相关文章

Skyeye 云智能制造办公系统 v3.16.6 发布

Skyeye 云智能制造&#xff0c;采用 Springboot (微服务) Layui UNI-APP Ant Design Vue 的低代码平台。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公…

Python+requests+pytest+allure自动化测试框架

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、核心库 requests request请求 openpyxl excel文件操作 loggin 日志 smtplib 发送邮件 configparser unittest.mock mock服务 2、目录结构 base utils …

06 APP 自动化- H5 元素定位

文章目录 H5 元素定位1、APP 分类2、H5 元素3、H5 元素定位环境的搭建4、代码实现&#xff1a; H5 元素定位 1、APP 分类 1、Android 原生 APP2、混合 APP(Android 原生控件H5页面)3、纯 H5 App 2、H5 元素 H5 元素容器 WebViewWebView 控件实现展示网页 3、H5 元素定位环…

项目计划未与实际情况同步更新,如何保持计划的实时性?

项目计划未与实际情况同步更新&#xff0c;可以通过建立实时更新机制、加强信息共享和沟通、引入敏捷管理工具、实施持续监控流程、明确计划更新责任来保持计划的实时性。 其中&#xff0c;建立实时更新机制至关重要。实时更新机制确保项目计划始终反映最新的进展和问题状况&am…

会议效率低下,应该怎么办

面对会议效率低下的问题&#xff0c;建议从以下几个方面进行优化&#xff1a;明确会议目标、控制会议时长、限定参与人员、使用协作工具、制定会议输出机制。其中&#xff0c;明确会议目标 是提升效率的关键起点。很多无效会议根源在于“为什么开会”这个问题没有回答清楚。只有…

LabVIEW基于 DataSocket从 OPC 服务器读取数据

LabVIEW 中基于 DataSocket 函数从 OPC 服务器读取数据的功能&#xff0c;为工业自动化等场景下的数据交互提供了解决方案。通过特定函数实现 URL 指定、连接建立与管理、数据读取&#xff0c;相比传统 Socket 通信和 RESTful API &#xff0c;在 OPC 服务器数据交互场景有适配…

数据挖掘顶刊《IEEE Transactions on Knowledge and Data Engineering》2025年5月研究热点都有些什么?

本推文对2025年5月出版的数据挖掘领域国际顶级期刊《IEEE Transactions on Knowledge and Data Engineering》进行了分析&#xff0c;对收录的62篇论文的关键词与研究主题进行了汇总&#xff0c;并对其中的研究热点进行了深入分析&#xff0c;希望能为相关领域的研究人员提供有…

结合 AI 生成 mermaid、plantuml 等图表

AI 画图 AI 画图并不是真的让 AI 画一个图片&#xff0c;而是让 AI 根据你的需求&#xff0c;生成对应的需求文本&#xff0c;再根据 “文本画图” 来生成图片。 Mermaid mermaid 支持流程图、时序图、架构图等等多种图片绘制。当然最终生成的效果和样式会根据不同的“文本代…

Java基础(二):八种基本数据类型详解

Java基础系列文章 Java基础(一)&#xff1a;发展史、技术体系与JDK环境配置详解 Java基础(二)&#xff1a;八种基本数据类型详解 目录 一、比特&#xff08;bit&#xff09;和字节&#xff08;Byte&#xff09;1、定义与换算关系2、应用场景差异 二、各类型详解1、整数类型&a…

数据安全合规体系构建的“三道防线“

引言 "三道防线"模型架构图 #mermaid-svg-wbeppAbwa3Vb3nL2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-wbeppAbwa3Vb3nL2 .error-icon{fill:#552222;}#mermaid-svg-wbeppAbwa3Vb3nL2 .error-text{fi…

MySQL强化关键_019_索引优化

目 录 一、最左前缀原则 1.完全使用索引 2.部分使用索引 3.不使用索引 4.效率折损 &#xff08;1&#xff09;使用范围查找 &#xff08;2&#xff09;索引断开 二、索引失效场景 1. 索引列参与运算 2.索引列模糊查询以“%”开始 3.索引列是字符串类型&#xff0c;查…

ABAP锁对象

1、锁表 在一些业务场景中&#xff0c;我们需要将某张表或某张表中的某些数据锁定&#xff0c;防止多人对该表进行操作&#xff0c;导致数据出现问题。SAP对于表的锁定&#xff0c;有专门的锁对象。 1.1、创建锁 事务代码SE11&#xff0c;表的锁对象名称&#xff0c;需要以E…

YOLO-V2 (学习记录)

目录 一、记录YOLO-v2 的处理流程步骤 二、优势与不足 三、细节分析 1.候选框K-means计算细节 2.网络输出 3.损失函数&#xff08;Loss Function&#xff09; 学习之前&#xff0c;需要补充下论文中提到知识点。 1.什么是Batch Normalization 参考博文&#xff1a;Batc…

AI Coding 资讯 2025-06-03

Prompt工程 RAG-MCP&#xff1a;突破大模型工具调用瓶颈&#xff0c;告别Prompt膨胀 大语言模型(LLM)在工具调用时面临Prompt膨胀和决策过载两大核心挑战。RAG-MCP创新性地引入检索增强生成技术&#xff0c;通过外部工具向量索引和动态检索机制&#xff0c;仅将最相关的工具信…

CAMEL-AI开源自动化任务执行助手OWL一键整合包下载

OWL 是由 CAMEL-AI 团队开发的开源多智能体协作框架&#xff0c;旨在通过动态智能体交互实现复杂任务的自动化处理&#xff0c;在 GAIA 基准测试中以 69.09 分位列开源框架榜首&#xff0c;被誉为“Manus 的开源平替”。我基于当前最新版本制作了免安装一键启动整合包。 CAMEL-…

线程池RejectedExecutionException异常

文章目录 1、报错2、定位3、修复4、线程池使用的一点思考 1、报错 检索项目日志时&#xff0c;发现一个异常堆栈信息&#xff0c;核心报错&#xff1a; java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.CompletableFuture$AsyncSupply480a10c7…

视频监控管理平台EasyCVR安防小知识:监控摄像头异响问题排查与处理

在视频监控系统广泛应用于日常生活的当下&#xff0c;监控摄像头出现异响是常见且影响使用体验的问题。为快速定位和解决该问题&#xff0c;特制定本应用解决方案&#xff0c;依据异响来源分为硬盘录像机异响与监控摄像头异响两类进行处理。 一、硬盘录像机发出异响 硬盘录像机…

NX890NX894美光固态闪存NX906NX908

美光NX系列固态闪存深度解析 技术架构与性能突破 美光NX系列固态闪存&#xff08;如NX890、NX894、NX906、NX908&#xff09;的技术核心基于G9 NAND技术&#xff0c;通过优化晶体管结构与制程工艺&#xff0c;显著提升存储密度与读写速度。例如&#xff0c;NX895的MT29F8T08G…

RHEL7安装教程

RHEL7安装教程 下载RHEL7镜像 通过网盘分享的文件&#xff1a;RHEL 7.zip 链接: https://pan.baidu.com/s/1ExLhdJigj-tcrHJxIca5XA?pwdjrrj 提取码: jrrj --来自百度网盘超级会员v6的分享安装 1.打开VMware&#xff0c;新建虚拟机&#xff0c;选择自定义然后下一步 2.点击…

无人机智能识别交通目标,AI视觉赋能城市交通治理新高度

在城市化快速发展的当下&#xff0c;如何实现对道路交通的智能化管理、保障出行安全&#xff0c;成为城市治理的重要命题。传统的交通监控往往依赖地面摄像头&#xff0c;受限于固定视角与安装环境。而今&#xff0c;随着人工智能与无人机技术的深度融合&#xff0c;一种更高效…