论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
DevOps与敏捷开发
›
分析JVM堆Dump日志定位线程阻塞缘故起因
分析JVM堆Dump日志定位线程阻塞缘故起因
九天猎人
金牌会员
|
2024-6-26 09:11:04
|
显示全部楼层
|
阅读模式
楼主
主题
991
|
帖子
991
|
积分
2973
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
堆Dump日志简介
JVM堆Dump日志是JVM在运行时内存的快照,它包罗了全部线程的状态、对象的引用关系、类加载信息等。当应用出现性能题目,如线程阻塞时,分析堆Dump日志可以资助我们找到题目标根源。
获取堆Dump日志
在JVM出现异常时,可以通过以下方式获取堆Dump:
手动触发
:使用jmap -dump:format=b,file=heapdump.hprof <pid>下令生成堆Dump。
配置JVM参数
:在启动JVM时加入-XX:+HeapDumpOnOutOfMemoryError参数,当发生内存溢出时主动生成堆Dump。
分析堆Dump日志
1. 使用jstack分析线程状态
jstack是JDK自带的一个堆栈跟踪工具,可以查看JVM中每个线程的调用栈信息。
jstack <pid>
复制代码
2. 辨认阻塞线程
在jstack的输出中,可以找随处于BLOCKED状态的线程。比方:
"Thread-2" #3 prio=5 os_prio=31 cpu=1.94ms elapsed=6.65s tid=0x00007f8e8f2a2800 nid=0x2 waiting for monitor entry
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b6e5e28> (a java.lang.String)
at java.lang.Object.wait(Object.java:502)
at com.example.MyService.waitForData(MyService.java:45)
- locked <0x000000076b6e5e28> (a java.lang.String)
复制代码
在这个例子中,Thread-1线程正在运行,但它正在等候锁定一个java.lang.String对象。
3. 确定锁的持有者
接下来,需要确定哪个线程持有这个锁。在jstack输出中,通常会表现持有锁的线程信息:
"Thread-1" #1 prio=5 os_prio=31 cpu=3.32ms elapsed=6.65s tid=0x00007f8e8f2a1000 nid=0x1 runnable
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
- waiting to lock <0x000000076b6e5e28> (a java.lang.String)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
- locked <0x000000076b6e5e28> (a java.lang.String)
at java.io.DataInputStream.readInt(DataInputStream.java:387)
at com.example.MyService.readData(MyService.java:23)
复制代码
在这个例子中,Thread-2正在等候Thread-1释放锁。
4. 使用MAT分析对象和线程
MAT(Memory Analyzer Tool)是一个强盛的堆Dump分析工具,可以资助我们可视化对象的引用关系和线程的状态。
打开MAT,加载堆Dump文件。
转到"Threads"视图,查看全部线程的状态。
转到"Dominator Tree"或"Histogram"视图,分析对象的内存占用和引用关系。
5. 检查死锁
如果怀疑存在死锁,可以使用jstack -l <pid>来获取死锁信息:
jstack -l <pid>
复制代码
MAT也提供了死锁检测功能,可以在"Deadlock Detector"视图中查看。
6. 优化代码
根据分析效果,可能需要进行代码优化,比如:
减少锁的范围。
使用更细粒度的锁。
制止在同步块中进行长时间的操作。
使用并发工具类,如java.util.concurrent包中的类。
示例
假设我们有以下Java代码:
public class Example {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread 1 acquired lock");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread 2 acquired lock");
}
});
t1.start();
t2.start();
}
}
复制代码
在这个例子中,Thread 1首先获取锁,然后Thread 2尝试获取同一个锁,导致Thread 2阻塞。通太过析堆Dump日志,我们可以确定Thread 2正在等候Thread 1释放锁。
通太过析JVM堆Dump日志,我们可以有用地定位线程阻塞的缘故起因,并采取相应的优化措施。这不仅有助于办理性能题目,还可以提升应用的稳固性和响应性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
九天猎人
金牌会员
这个人很懒什么都没写!
楼主热帖
C# 使用流读取大型TXT文本文件 ...
从洞察到决策,一文解读标签画像体系建 ...
袋鼠云平台代码规范化编译部署的提效性 ...
Flink的API分层、架构与组件原理、并行 ...
SpringBoot(八) - 统一数据返回,统一 ...
Redis命令手册
打穿你的内网之三层内网渗透 ...
JVM
微服务(三)之负载均衡(服务端和客户端) ...
MVCC - Read View的可见性判断理解 ...
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
物联网
Oracle
分布式数据库
SQL-Server
Java
快速回复
返回顶部
返回列表