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

工欲善其事,必先利其器

簡介

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

一、Java死鎖排查

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

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

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

解答

  1. 什么是死鎖?

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

死鎖圖示

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

  1. 為什么會出現(xiàn)死鎖?

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

  1. 怎么排查代碼中出現(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請自行查詢資料】

jps -l 命令

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


jstack

使用jconsole

在window打開 JConsole,JConsole是一個圖形化的監(jiān)控工具!

在windons命令窗口 ,輸出 JConsole


這里寫圖片描述
這里寫圖片描述

使用Java Visual VM

在window打開 jvisualvm,jvisualvm是一個圖形化的監(jiān)控工具!

在windons命令窗口 ,輸出 jvisualvm

Java Visual VM
死鎖檢測

二、Java CPU 100% 排查

這個如果在實際的應(yīng)用開發(fā)中遇到,要怎么排查呢?

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

1 、 使用top命令查看cpu占用資源較高的PID


top命令

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,注意是小寫!

巧轉(zhuǎn)進制

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博客,我們一同成長!

不管做什么,只要堅持下去就會看到不一樣!在路上,不卑不亢!

博客首頁 : http://blog.csdn.net/u010648555

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容