工欲善其事,必先利其器
簡介
本篇整理兩個排查問題的簡單技巧,一個是java死鎖排查,這個一般在面試的時會問到,如果沒有寫多線程的話,實際中遇到的機會不多;第二個是java cpu 100%排查,這個實際的開發(fā)中,線的應(yīng)用出現(xiàn)這個問題可能性比較大,所以這里簡單總結(jié)介紹一下,對自己學習知識的一個整理,提高自己的解決問題能力。
一、Java死鎖排查
通過標題我們就要思考三個問題:
- 什么是死鎖?
- 為什么會出現(xiàn)死鎖?
- 怎么排查代碼中出現(xiàn)了死鎖?
作為技術(shù)人員(工程師),在面對問題的時候,可能需要的能力是怎么去解決這個問題。但是在學習技術(shù)知識的時候,那就要多問為什么,一定要鍛煉自己這方面的能力,這樣才能更好的掌握知識。
解答:
- 什么是死鎖?
死鎖是指兩個或兩個以上的進程在執(zhí)行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現(xiàn)象,若無外力作用,它們都將無法推進下去。此時稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。百度百科:死鎖
注:進程和線程都可以發(fā)生死鎖,只要滿足死鎖的條件!
- 為什么會出現(xiàn)死鎖?
從上面的概念中我們知道
(1)必須是兩個或者兩個以上進程(線程)
(2)必須有競爭資源
- 怎么排查代碼中出現(xiàn)了死鎖?【重點來了】
首先寫一個死鎖的代碼,看例子:
/**
*
* 使用jstack 排查死鎖
* @author dufyun
*
*/
public class JStackDemo {
public static void main(String[] args) {
Thread t1 = new Thread(new DeadLockTest(true));//建立一個線程
Thread t2 = new Thread(new DeadLockTest(false));//建立另一個線程
t1.setName("thread-dufy-1");
t2.setName("thread-dufy-2");
t1.start();//啟動一個線程
t2.start();//啟動另一個線程
}
}
class DeadLockTest implements Runnable {
public boolean falg;// 控制線程
DeadLockTest(boolean falg) {
this.falg = falg;
}
public void run() {
/**
* 如果falg的值為true則調(diào)用t1線程
*/
if (falg) {
while (true) {
synchronized (Demo.o1) {
System.out.println("o1 " + Thread.currentThread().getName());
synchronized (Demo.o2) {
System.out.println("o2 " + Thread.currentThread().getName());
}
}
}
}
/**
* 如果falg的值為false則調(diào)用t2線程
*/
else {
while (true) {
synchronized (Demo.o2) {
System.out.println("o2 " + Thread.currentThread().getName());
synchronized (Demo.o1) {
System.out.println("o1 " + Thread.currentThread().getName());
}
}
}
}
}
}
class Demo {
static Object o1 = new Object();
static Object o2 = new Object();
}
上面這段代碼執(zhí)行后,就會出現(xiàn)死鎖,那么排查的方法有如下:
使用 jps + jstack
第一:在windons命令窗口,使用 jps -l 【不會使用jps請自行查詢資料】
第二:使用jstack -l 12316 【不會使用jstack請自行查詢資料】
jstack
使用jconsole
在window打開 JConsole,JConsole是一個圖形化的監(jiān)控工具!
在windons命令窗口 ,輸出 JConsole
這里寫圖片描述
使用Java Visual VM
在window打開 jvisualvm,jvisualvm是一個圖形化的監(jiān)控工具!
在windons命令窗口 ,輸出 jvisualvm
二、Java CPU 100% 排查
這個如果在實際的應(yīng)用開發(fā)中遇到,要怎么排查呢?
這里沒有一步步的圖示過程,只有一個簡單的操作過程!有空寫一個詳細的例子。
1 、 使用top命令查看cpu占用資源較高的PID
2、 通過jps 找到當前用戶下的java程序PID
執(zhí)行 jps -l 能夠打印出所有的應(yīng)用的PID,找到有一個PID和這個cpu使用100%一樣的ID!!就知道是哪一個服務(wù)了。
3、 使用 pidstat -p <PID> 1 3 -u -t
4 、 找到cpu占用較高的線程TID
通過上圖發(fā)現(xiàn)是 3467的TID占用cup較大
5、 將TID轉(zhuǎn)換為十六進制的表示方式
將3467轉(zhuǎn)為十六進制 d8d,注意是小寫!
6、 通過jstack -l <PID> 輸出當前進程的線程信息
使用jstack 輸出當前PID的線程dunp信息
7、 查找 TID對應(yīng)的線程(輸出的線程id為十六進制),找到對應(yīng)的代碼
三、壓力測試使用jstack找到系統(tǒng)的代碼性能問題
1、在進行壓力測試的時候,使用jps找到應(yīng)用的PID
2、然后使用jstack輸出出壓力測試時候應(yīng)用的dump信息
3、分析輸出的日志文件中那個方法block線程占用最多,這里可能是性能有問題,找到對應(yīng)的代碼分析
參考
1、Java應(yīng)用CPU占用100%原因分析
2、[Java] CPU 100% 原因查找解決
3、線上應(yīng)用故障排查系列
4、分析JAVA應(yīng)用CPU占用過高的問題
如果您覺得這篇博文對你有幫助,請點贊或者喜歡,讓更多的人看到,謝謝!
如果帥氣(美麗)、睿智(聰穎),和我一樣簡單善良的你看到本篇博文中存在問題,請指出,我虛心接受你讓我成長的批評,謝謝閱讀!
祝你今天開心愉快!
歡迎訪問我的csdn博客,我們一同成長!
不管做什么,只要堅持下去就會看到不一樣!在路上,不卑不亢!