Java死鎖排查和Java CPU 100% 排查的步驟整理(轉)


 

工欲善其事,必先利其器

簡介

本篇整理兩個排查問題的簡單技巧,一個是java死鎖排查,這個一般在面試的時會問到,如果沒有寫多線程的話,實際中遇到的機會不多;第二個是java cpu 100%排查,這個實際的開發中,線的應用出現這個問題可能性比較大,所以這里簡單總結介紹一下,對自己學習知識的一個整理,提高自己的解決問題能力。

一、Java死鎖排查

通過標題我們就要思考三個問題:

  1. 什么是死鎖?
  2. 為什么會出現死鎖?
  3. 怎么排查代碼中出現了死鎖?

作為技術人員(工程師),在面對問題的時候,可能需要的能力是怎么去解決這個問題。但是在學習技術知識的時候,那就要多問為什么,一定要鍛煉自己這方面的能力,這樣才能更好的掌握知識。

解答

  1. 什么是死鎖?

    死鎖是指兩個或兩個以上的進程在執行過程中,由於競爭資源或者由於彼此通信而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。百度百科:死鎖

死鎖圖示

注:進程和線程都可以發生死鎖,只要滿足死鎖的條件!

  1. 為什么會出現死鎖?

    從上面的概念中我們知道
    (1)必須是兩個或者兩個以上進程(線程)
    (2)必須有競爭資源

  2. 怎么排查代碼中出現了死鎖?【重點來了
    首先寫一個死鎖的代碼,看例子:


/** * * 使用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則調用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則調用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(); } 

上面這段代碼執行后,就會出現死鎖,那么排查的方法有如下:

使用 jps + jstack

第一:在windons命令窗口,使用 jps -l 【不會使用jps請自行查詢資料】

jps -l 命令

第二:使用jstack -l 12316 【不會使用jstack請自行查詢資料】
jstack

使用jconsole

在window打開 JConsole,JConsole是一個圖形化的監控工具!

在windons命令窗口 ,輸出 JConsole
這里寫圖片描述

這里寫圖片描述

使用Java Visual VM

在window打開 jvisualvm,jvisualvm是一個圖形化的監控工具!

在windons命令窗口 ,輸出 jvisualvm

Java Visual VM

死鎖檢測

二、Java CPU 100% 排查

這個如果在實際的應用開發中遇到,要怎么排查呢?

這里沒有一步步的圖示過程,只有一個簡單的操作過程!有空寫一個詳細的例子。

1 、 使用top命令查看cpu占用資源較高的PID
top命令
2、 通過jps 找到當前用戶下的java程序PID

執行 jps -l 能夠打印出所有的應用的PID,找到有一個PID和這個cpu使用100%一樣的ID!!就知道是哪一個服務了。

3、 使用 pidstat -p 1 3 -u -t

這里寫圖片描述

4 、 找到cpu占用較高的線程TID

通過上圖發現是 3467的TID占用cup較大

5、 將TID轉換為十六進制的表示方式

將3467轉為十六進制 d8d,注意是小寫!

巧轉進制
6、 通過jstack -l 輸出當前進程的線程信息

使用jstack 輸出當前PID的線程dunp信息

7、 查找 TID對應的線程(輸出的線程id為十六進制),找到對應的代碼

查找

三、壓力測試使用jstack找到系統的代碼性能問題

1、在進行壓力測試的時候,使用jps找到應用的PID
2、然后使用jstack輸出出壓力測試時候應用的dump信息
3、分析輸出的日志文件中那個方法block線程占用最多,這里可能是性能有問題,找到對應的代碼分析

參考

1、Java應用CPU占用100%原因分析
2、[Java] CPU 100% 原因查找解決
3、線上應用故障排查系列
4、分析JAVA應用CPU占用過高的問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM