欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java如何通過jstack命令查詢?nèi)罩?/h1>
 更新時間:2023年03月21日 14:54:33   作者:吳名氏  
在分析線上問題時常使用到jstack?<PID>命令將當時Java應用程序的線程堆棧dump出來,面對jstack?日志,我們?nèi)绾尾榭??下面小編給大家介紹下Java如何通過jstack命令查詢?nèi)罩?,感興趣的朋友一起看看吧

在分析線上問題時常使用到jstack <PID>命令將當時Java應用程序的線程堆棧dump出來。

面對jstack 日志,我們?nèi)绾尾榭矗?/p>

1 首先要清楚線程的狀態(tài)

線程的狀態(tài)有: new、runnable、running、waiting、timed_waiting、blocked、dead

1.1 線程狀態(tài)變遷圖:

1.2 各狀態(tài)說明:

New: 當線程對象創(chuàng)建時存在的狀態(tài),此時線程不可能執(zhí)行;

Runnable:當調(diào)用thread.start()后,線程變成為Runnable狀態(tài)。只要得到CPU,就可以執(zhí)行;

Running:線程正在執(zhí)行;

Waiting:執(zhí)行thread.join()或在鎖對象調(diào)用obj.wait()等情況就會進該狀態(tài),表明線程正處于等待某個資源或條件發(fā)生來喚醒自己;

Timed_Waiting:執(zhí)行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就會進該狀態(tài),與Waiting的區(qū)別在于Timed_Waiting的等待有時間限制;

Blocked:如果進入同步方法或同步代碼塊,沒有獲取到鎖,則會進入該狀態(tài);

Dead:線程執(zhí)行完畢,或者拋出了未捕獲的異常之后,會進入dead狀態(tài),表示該線程結(jié)束

1.3 對于jstack日志,我們要著重關(guān)注如下關(guān)鍵信息

Deadlock:表示有死鎖

Waiting on condition:等待某個資源或條件發(fā)生來喚醒自己。具體需要結(jié)合jstacktrace來分析,比如線程正在sleep,網(wǎng)絡讀寫繁忙而等待

Blocked:阻塞

Waiting on monitor entry:在等待獲取鎖

in Object.wait():獲取鎖后又執(zhí)行obj.wait()放棄鎖

1.4 Waiting on monitor entry 和 in Object.wait()的詳細描述

Monitor是 Java中用以實現(xiàn)線程之間的互斥與協(xié)作的主要手段,它可以看成是對象或者 Class的鎖。每一個對象都有,也僅有一個 monitor。從下圖中可以看出,每個 Monitor在某個時刻,只能被一個線程擁有,該線程就是 "Active Thread",而其它線程都是 "Waiting Thread",分別在兩個隊列 " Entry Set"和 "Wait Set"里面等候。在 "Entry Set"中等待的線程狀態(tài)是 "Waiting for monitor entry",而在 "Wait Set"中等待的線程狀態(tài)是 "in Object.wait()"

2 舉例說明

2.1 blocked 的例子

程序先輸出main,在輸出thread,說明mian的線程是先獲得同步鎖的

執(zhí)行jstack pid輸出信息如下:

可以看到thread1在進行等待獲取到鎖,此時進入waiting for monitor entry,并是阻塞狀態(tài)。

而main線程提前獲取到鎖,當由于調(diào)用了sleep此時進入到Timed_waiting狀態(tài),此時man線程鎖住的對象地址是7f3167cf0,而thread1正在等待獲取這個鎖對象。

prio:線程的優(yōu)先級

tid:線程id

nid:操作系統(tǒng)映射的線程id, 非常關(guān)鍵,后面再使用jstack時補充

1103e9000和106692000 :表示線程棧的起始地址。

從jstack日志中,可以看到:主線程獲取到thread2對象上的鎖,因此正在執(zhí)行sleep操作,狀態(tài)為TIMED_WAINTING, 而thread2由于未獲取到thread2對象上的鎖,因此處于BLOCKED狀態(tài)。

再細看,thread2 正在"waiting to lock <7f3167cf0>",即試圖在地址為7f3167cf0所在的對象獲取鎖,而該鎖卻被main線程占有(locked <7f3167cf0>)。main線程正在"waiting on condition",說明正在等待某個條件觸發(fā),由jstacktrace來看,此線程正在sleep。

經(jīng)驗:

如果在jstack日志發(fā)現(xiàn)大量的線程在waiting to lock 某個地址,只要能查到哪個線程獲取到鎖就可以方便定位問題了

2.2 object.wait()

    public static void main(String[] args) {
 
        final Thread thread = new Thread() {
 
            @Override
 
            public void run() {
 
                synchronized (this) {
 
                    System.out.println(Thread.currentThread().getName());
 
                    try {
 
                        wait();
 
                    } catch (InterruptedException e) {
 
                        // TODO Auto-generated catch block
 
                        e.printStackTrace();
 
                    }
 
                }
 
            }
 
        };
 
        thread.start();
 
        thread.setName("zouxh");//起名字,方便在線程棧里面進行查看
 
        try {
 
            TimeUnit.SECONDS.sleep(3);
 
        } catch (InterruptedException e) {
 
            // TODO Auto-generated catch block
 
            e.printStackTrace();
 
        }
 
        synchronized (thread) {
 
            System.out.println(Thread.currentThread().getName());
 
            try {
 
                TimeUnit.SECONDS.sleep(30);
 
            } catch (InterruptedException e) {
 
                // TODO Auto-generated catch block
 
                e.printStackTrace();
 
            }
 
            thread.notify();
 
        }
 
    }

執(zhí)行后,查看jstack的日志如下:

"zouxh" prio=5 tid=7fe18c97b800 nid=0x115e58000 in Object.wait() [115e57000]

java.lang.Thread.State: WAITING (on object monitor)

at java.lang.Object.wait(Native Method)

- waiting on <7f3112fe8> (a jstat.MainWati$1)

at java.lang.Object.wait(Object.java:485)

at jstat.MainWati$1.run(MainWati.java:16)

- locked <7f3112fe8> (a jstat.MainWati$1)

"main" prio=5 tid=7fe18c000800 nid=0x10c47b000

waiting on condition [10c47a000]

java.lang.Thread.State: TIMED_WAITING (sleeping)

at java.lang.Thread.sleep(Native Method)

at java.lang.Thread.sleep(Thread.java:300)

at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:328)

at jstat.MainWati.main(MainWati.java:37)

- locked <7f3112fe8> (a jstat.MainWati$1)

可以看到由于調(diào)用了object.wait()方法的時候放棄了鎖,所以zouxh這個線程就出現(xiàn)了object.wait()狀態(tài),線程的狀態(tài)就是waiting,等待notify來進行喚醒。

由于mian線程在獲得zouxh的線程鎖后,調(diào)用了sleep方法,所以此時進入了wating on condition等待某一個資源,進入到time_waiting狀態(tài)。

2.3 waiting on conditon

    private static BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(1);
 
    public static void main(String[] args) {
 
        blockingQueue.add("zouxh");
 
        try {
 
            //阻塞的添加
 
            blockingQueue.put("ssss");
 
        } catch (InterruptedException e) {
 
            // TODO Auto-generated catch block
 
            e.printStackTrace();
 
        }
 
    }

線程棧如下:

"main" prio=5 tid=7f8f65000800 nid=0x10d7bb000 waiting on condition [10d7ba000]

java.lang.Thread.State: WAITING (parking)

at sun.misc.Unsafe.park(Native Method)

- parking to wait for <7f3110d80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)

at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)

at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:257)

at jstat.WatingTest.main(WatingTest.java:13)

此時main線程進入了waiting on conditon狀態(tài),等待某一個資源,此時可以看到是在

a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObjec進行了等待,阻塞住了,這是由于put發(fā)生了阻塞。

3 總結(jié)

對于jstack日志,我們要著重關(guān)注如下關(guān)鍵信息

Deadlock:表示有死鎖

Waiting on condition:等待某個資源或條件發(fā)生來喚醒自己。具體需要結(jié)合jstacktrace來分析,比如線程正在sleep,網(wǎng)絡讀寫繁忙而等待

Blocked:阻塞

Waiting on monitor entry:在等待獲取鎖

如果說系統(tǒng)慢,那么要特別關(guān)注Blocked,Waiting on condition

如果說系統(tǒng)的cpu耗的高,那么肯定是線程執(zhí)行有死循環(huán),那么此時要關(guān)注下Runable狀態(tài)。

到此這篇關(guān)于java通過jstack命令查詢?nèi)罩镜奈恼戮徒榻B到這了,更多相關(guān)java jstack命令查詢?nèi)罩緝?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中使用json與前臺Ajax數(shù)據(jù)交互的方法

    Java中使用json與前臺Ajax數(shù)據(jù)交互的方法

    這篇文章主要為大家詳細介紹了Java中使用json與前臺Ajax數(shù)據(jù)交互的方法,分享Ajax獲取顯示Json數(shù)據(jù)的一種方法,感興趣的小伙伴們可以參考一下
    2016-06-06
  • 淺談 JDBC 元數(shù)據(jù)

    淺談 JDBC 元數(shù)據(jù)

    這篇文章主要介紹了JDBC元數(shù)據(jù)的相關(guān)內(nèi)容,涉及一些獲取數(shù)據(jù)源各種信息的方法,具有一定參考價值,需要的朋友可以了解下。
    2017-09-09
  • 拳皇(Java簡單的小程序)代碼實例

    拳皇(Java簡單的小程序)代碼實例

    這篇文章主要介紹了拳皇Java簡單小程序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • Java實現(xiàn)樹形菜單的方法總結(jié)

    Java實現(xiàn)樹形菜單的方法總結(jié)

    當我們想要展示層級結(jié)構(gòu),如文件目錄、組織結(jié)構(gòu)或分類目錄時,樹形菜單是一個直觀且有效的解決方案,本文為大家整理了java中幾種常見方法,希望對大家有所幫助
    2023-08-08
  • SpringCloud Gateway中斷言路由和過濾器的使用詳解

    SpringCloud Gateway中斷言路由和過濾器的使用詳解

    這篇文章主要介紹了SpringCloud Gateway中斷言路由和過濾器的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Spring?Boot?接口加解密功能實現(xiàn)

    Spring?Boot?接口加解密功能實現(xiàn)

    在我們?nèi)粘5腏ava開發(fā)中,免不了和其他系統(tǒng)的業(yè)務交互,或者微服務之間的接口調(diào)用;如果我們想保證數(shù)據(jù)傳輸?shù)陌踩?,對接口出參加密,入?yún)⒔饷埽@篇文章主要介紹了Spring?Boot?接口加解密功能實現(xiàn),需要的朋友可以參考下
    2023-04-04
  • win10系統(tǒng)64位jdk1.8的下載與安裝教程圖解

    win10系統(tǒng)64位jdk1.8的下載與安裝教程圖解

    這篇文章主要介紹了win10系統(tǒng)64位jdk1.8的下載與安裝教程圖解,本文給大家介紹的非常詳細,對大家的工作或?qū)W習具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Mybatis動態(tài)Sql標簽使用小結(jié)

    Mybatis動態(tài)Sql標簽使用小結(jié)

    本文主要介紹了Mybatis動態(tài)Sql標簽使用,常用的動態(tài)sql標簽包括?if、choose(when、otherwise)、trim(where、set)、foreach,下面就來介紹一下
    2024-04-04
  • java優(yōu)化if-else的11種方案

    java優(yōu)化if-else的11種方案

    If-Else結(jié)構(gòu)是一種常見的條件判斷語句,通過優(yōu)化If-Else結(jié)構(gòu),可以提高代碼的可讀性和執(zhí)行效率,本文主要介紹了java優(yōu)化if-else的11種方案,感興趣的可以了解一下
    2024-08-08
  • java用靜態(tài)工廠代替構(gòu)造函數(shù)使用方法和優(yōu)缺點

    java用靜態(tài)工廠代替構(gòu)造函數(shù)使用方法和優(yōu)缺點

    這篇文章主要介紹了java用靜態(tài)工廠代替構(gòu)造函數(shù)使用方法和優(yōu)缺點,需要的朋友可以參考下
    2014-02-02

最新評論