惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
罗磊的独立博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
云风的 BLOG
云风的 BLOG
T
The Blog of Author Tim Ferriss
Y
Y Combinator Blog
A
About on SuperTechFans
WordPress大学
WordPress大学
B
Blog
Martin Fowler
Martin Fowler
Jina AI
Jina AI
I
InfoQ
P
Proofpoint News Feed
小众软件
小众软件
S
SegmentFault 最新的问题
V
V2EX
B
Blog RSS Feed
量子位
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
MongoDB | Blog
MongoDB | Blog
美团技术团队

浮华生

Elasticsearch 检索性能优化 - 浮华生 舆情监控系统综述 - 浮华生 2024 半年度总结 - 浮华生 2023 年终总结 - 浮华生 异地机器组网方案 - 浮华生 Kubernetes 部署 Elasticsearch 和 Kibana - 浮华生 2022 年终总结 - 浮华生 RabbitMQ connection channel 的关系 - 浮华生 Kafka Java 客户端 Producer 原理分析 - 浮华生 RabbitMQ 和 Kafka 应用原理简单对比 - 浮华生 阿里云 OpenSearch 介绍 - 浮华生 Golang Array 和 Slice 区别 - 浮华生 Mac OS 下打造 golang nvim 编程环境之基础配置 - 浮华生 电商搜索技术总结 - 浮华生 电商搜索业务总结 - 浮华生 2021 年终总结 - 浮华生 Cypress 实践总结 - 浮华生 年终总结 - 浮华生 关于我 - 浮华生 使用 cucumber 进行行为驱动开发(BDD) - 浮华生 微服务应用集成 SpringCloud 步骤 - 浮华生 电商搜索数据同步方案 - 浮华生 通过一道数值转换题重温计算机补码 - 浮华生 macOS 系统推荐的一些软件 - 浮华生 DevOps 实施规划(持续更新) - 浮华生 rabbitmq 如何提高可靠性并保证消费端幂等 - 浮华生 AMQ Model总结 - 浮华生 结对编程 - 浮华生 RSocket 介绍 - 浮华生 面向对象的理解 - 浮华生
jstack 死循环和死锁定位 - 浮华生
浮华生 · 2018-09-03 · via 浮华生

文章目录

2018年9月3日

| 阅读

jstack 是用来查看线程的命令

先来看看线程的状态(官方文档)

  • New
  • Runnable
  • Blocked
  • Waiting
  • Timed_Waiting
  • Terminated

下面是 java 线程状态转化 thread

代码模拟

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@RestController
public class CpuController {
	
	/**
	 * 死循环
	 * */
	@RequestMapping("/loop")
	public List<Long> loop(){
		String data = "{\"data\":[{\"partnerid\":]";
		return getPartneridsFromJson(data);
	}
	
	private Object lock1 = new Object();
	private Object lock2 = new Object();
	
	/**
	 * 死锁
	 * */
	@RequestMapping("/deadlock")
	public String deadlock(){
		new Thread(()->{
			synchronized(lock1) {
				try {Thread.sleep(1000);}catch(Exception e) {}
				synchronized(lock2) {
					System.out.println("Thread1 over");
				}
			}
		}) .start();
		new Thread(()->{
			synchronized(lock2) {
				try {Thread.sleep(1000);}catch(Exception e) {}
				synchronized(lock1) {
					System.out.println("Thread2 over");
				}
			}
		}) .start();
		return "deadlock";
	}
	public static List<Long> getPartneridsFromJson(String data){  
	    //{\"data\":[{\"partnerid\":982,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":983,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":984,\"count\":\"10000\",\"cityid\":\"11\"}]}  
	    //上面是正常的数据  
	    List<Long> list = new ArrayList<Long>(2);  
	    if(data == null || data.length() <= 0){  
	        return list;  
	    }      
	    int datapos = data.indexOf("data");  
	    if(datapos < 0){  
	        return list;  
	    }  
	    int leftBracket = data.indexOf("[",datapos);  
	    int rightBracket= data.indexOf("]",datapos);  
	    if(leftBracket < 0 || rightBracket < 0){  
	        return list;  
	    }  
	    String partners = data.substring(leftBracket+1,rightBracket);  
	    if(partners == null || partners.length() <= 0){  
	        return list;  
	    }  
	    while(partners!=null && partners.length() > 0){  
	        int idpos = partners.indexOf("partnerid");  
	        if(idpos < 0){  
	            break;  
	        }  
	        int colonpos = partners.indexOf(":",idpos);  
	        int commapos = partners.indexOf(",",idpos);  
	        if(colonpos < 0 || commapos < 0){  
	            //partners = partners.substring(idpos+"partnerid".length());//1  
	            continue;
	        }  
	        String pid = partners.substring(colonpos+1,commapos);  
	        if(pid == null || pid.length() <= 0){  
	            //partners = partners.substring(idpos+"partnerid".length());//2  
	            continue;
	        }  
	        try{  
	            list.add(Long.parseLong(pid));  
	        }catch(Exception e){  
	            //do nothing  
	        }  
	        partners = partners.substring(commapos);  
	    }  
	    return list;  
	}  
	
}

死循环定位

1
2
3
4
top 
jstack <pid> > result.txt #将结果追加到 txt 文件


负载过大会导致无法访问,使用 top 命名找到占用 cpu 最多的那个进程,

top -p <pid> -H #打印所有的线程
printf "%x" <pid> 将十进制的 pid 转换成 十六进制
找到线程对应的 pid 

死锁定位

1
2
jps -l #或者 ps -ef | grep java
jstack <pid> > result.txt

如果有死锁则会在文件末尾出现提示。


comments powered by