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

java堆棧跟蹤工具jstack的使用教程

 更新時(shí)間:2023年11月14日 08:41:25   作者:242030  
jstack(stack?trace?for?java)是java虛擬機(jī)自帶的一種堆棧跟蹤工具,主要用于生成java虛擬機(jī)當(dāng)前時(shí)刻的線程快照,下面我們就來學(xué)習(xí)一下它的具體使用吧

1、jstack介紹

jstack(stack trace for java)是java虛擬機(jī)自帶的一種堆棧跟蹤工具。

jstack主要用于生成java虛擬機(jī)當(dāng)前時(shí)刻的線程快照,線程快照是當(dāng)前java虛擬機(jī)內(nèi)每一條線程正在執(zhí)行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現(xiàn)長時(shí)間停頓的原因,如線程間死鎖、死循環(huán)、請求外部資源導(dǎo)致的長時(shí)間等待等。

線程出現(xiàn)停頓的時(shí)候通過jstack來查看各個(gè)線程的調(diào)用堆棧,就可以知道沒有響應(yīng)的線程到底在后臺做什么事情,或者等待什么資源。

jstack主要分為兩個(gè)功能:

  • 針對活著的進(jìn)程做本地的或遠(yuǎn)程的線程dump
  • 針對core文件做線程dump

當(dāng)指定的進(jìn)程在64位Java虛擬機(jī)上運(yùn)行時(shí),可能需要指定-J-d64選項(xiàng),例如:jstack -J-d64 -m pid。

2、線程狀態(tài)

線程通常有下面5中狀態(tài):

1、新建狀態(tài)(New): 新創(chuàng)建了一個(gè)線程對象。

2、就緒狀態(tài)(Runnable) :線程對象創(chuàng)建后,其他線程調(diào)用了該對象的start()方法。該狀態(tài)的線程位于可運(yùn)行線程池中,變得可運(yùn)行,等待獲取CPU的使用權(quán)。

3、運(yùn)行狀態(tài)(Running): 就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼。

4、阻塞狀態(tài)(Blocked): 阻塞狀態(tài)是線程因?yàn)槟撤N原因放棄CPU使用權(quán),暫時(shí)停止運(yùn)行。直到線程進(jìn)入就緒狀態(tài),才有機(jī)會轉(zhuǎn)到運(yùn)行狀態(tài)。阻塞的情況分三種:

等待阻塞:運(yùn)行的線程執(zhí)行wait()方法,JVM會把該線程放入等待池中。

同步阻塞:運(yùn)行的線程在獲取對象的同步鎖時(shí),若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中。

其他阻塞:運(yùn)行的線程執(zhí)行sleep()或join()方法,或者發(fā)出了I/O請求時(shí),JVM會把該線程置為阻塞狀態(tài)。

當(dāng)sleep()狀態(tài)超時(shí)、join()等待線程終止或者超時(shí)、或者I/O處理完畢時(shí),線程重新轉(zhuǎn)入就緒狀態(tài)。

5、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。

關(guān)于線程狀態(tài),具體也可以查看:java.lang.Thread.State類。

想要通過jstack命令來分析線程的情況的話,首先要知道線程都有哪些狀態(tài),下面這些狀態(tài)是我們使用jstack命

令查看線程堆棧信息時(shí)可能會看到的線程的幾種狀態(tài):

  • RUNNABLE,線程運(yùn)行中或I/O等待
  • BLOCKED,線程被阻塞,在等待monitor鎖(synchronized關(guān)鍵字)
  • TIMED_WAITING ,線程在等待喚醒,但設(shè)置了時(shí)限
  • WAITING ,線程在無限等待喚醒

在線程的堆棧中,需要特別留意以下幾種狀態(tài):

  • Deadlock: 死鎖(重點(diǎn)關(guān)注)
  • Waiting on condition: 等待資源(重點(diǎn)關(guān)注)
  • Waiting on monitor entry : 等待獲取監(jiān)視器(重點(diǎn)關(guān)注)
  • Blocked :阻塞(重點(diǎn)關(guān)注)
  • Runnable :執(zhí)行中
  • Suspended : 暫停
  • Object.wait()或TIME_WAITING :對象等待中
  • Parked : 停止

3、jstack命令格式

jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP

pid:Java進(jìn)程的ID,可以通過jps命令查詢到。

executable: 產(chǎn)生core dump的Java可執(zhí)行程序。

core:要打印的堆棧跟蹤的核心文件。

server-id:當(dāng)多個(gè)DEBUG服務(wù)器在同一遠(yuǎn)程主機(jī)上運(yùn)行時(shí),可使用的可選唯一ID。

remote-hostname-or-IP:遠(yuǎn)程DEBUG的服務(wù)器主機(jī)名或IP地址。

pid: 需要被打印配置信息的java進(jìn)程id,可以用jps查詢。

常用參數(shù)說明:

-F:當(dāng) jstack [-l] pid 沒有響應(yīng)時(shí),強(qiáng)制打印一個(gè)堆棧轉(zhuǎn)儲。

-l:打印關(guān)于鎖的其他信息,比如擁有的java.util.concurrent ownable同步器的列表,會使得JVM停頓得長久得多。

-m:打印包含Java和本機(jī)C/ C++幀的混合模式堆棧跟蹤。

-h:打印幫助信息。

-help:打印幫助信息。

3.1 jstack pid

第一行各個(gè)單詞的解析,

daemon:線程名稱 。

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

tid:指Java Thread id。

nid:指native線程的id。。

[0x000000002369e000]:線程棧起始地址。

3.2 死循環(huán)

package com.example.controller;

public class Test2 {

    public static void main(String[] args) {
        while (true) {
        }
    }
    
}

3.3 Object.wait()情況

package com.example.controller;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test3 {
    static class TestTask implements Runnable {
        @Override
        public void run() {
            synchronized (this) {
                try {
                    //等待被喚醒
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ExecutorService ex = Executors.newFixedThreadPool(1);
        ex.execute(new TestTask());
    }
}

3.4 死鎖情況

package com.example.controller;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test4 {

    public static void main(String[] args) {
        Object obj1 = new Object();
        Object obj2 = new Object();
        ExecutorService ex = Executors.newFixedThreadPool(2);
        // 起10個(gè)線程
        for (int i = 0; i < 10; i++) {
            int order = i % 2 == 0 ? 1 : 0;
            ex.execute(new TestTask(order, obj1, obj2));
        }
    }

    static class TestTask implements Runnable {
        private Object obj1;
        private Object obj2;
        private int order;

        public TestTask(int order, Object obj1, Object obj2) {
            this.order = order;
            this.obj1 = obj1;
            this.obj2 = obj2;
        }

        public void test1() throws InterruptedException {
            synchronized (obj1) {
                synchronized (obj2) {
                    System.out.println("test。。。");
                }
            }
        }

        public void test2() throws InterruptedException {
            synchronized (obj2) {
                synchronized (obj1) {
                    System.out.println("test。。。");
                }
            }
        }

        @Override
        public void run() {
            while (true) {
                try {
                    if (this.order == 1) {
                        this.test1();
                    } else {
                        this.test2();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.5 等待io

package com.example.controller;

import java.io.IOException;
import java.io.InputStream;

public class Test5 {

    public static void main(String[] args) throws IOException {
        InputStream is = System.in;
        int i = is.read();
        System.out.println("exit。");
    }

}

以上就是java堆棧跟蹤工具jstack的使用教程的詳細(xì)內(nèi)容,更多關(guān)于java jstack的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java多線程之Future和FutureTask使用實(shí)例

    java多線程之Future和FutureTask使用實(shí)例

    這篇文章主要介紹了java多線程之Future和FutureTask使用實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 使用Java實(shí)現(xiàn)一個(gè)能保留計(jì)算過程的計(jì)算器

    使用Java實(shí)現(xiàn)一個(gè)能保留計(jì)算過程的計(jì)算器

    計(jì)算器是我們?nèi)粘I钪谐S玫墓ぞ咧?它能夠進(jìn)行基本的數(shù)學(xué)運(yùn)算,如加法、減法、乘法和除法,而在設(shè)計(jì)一個(gè)計(jì)算器時(shí),我們可以通過使用Java編程語言來實(shí)現(xiàn)一個(gè)簡單的控制臺計(jì)算器,并且讓它能夠保留計(jì)算過程,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-11-11
  • Java枚舉之EnumSet詳解

    Java枚舉之EnumSet詳解

    這篇文章主要介紹了Java枚舉之EnumSet詳解,使用時(shí)進(jìn)行與或運(yùn)算,但是定義多了之后,會很亂、臃腫,編寫容易出錯(cuò),EnumSet可以實(shí)現(xiàn)類似的功能,且使用起來很簡潔,需要的朋友可以參考下
    2023-12-12
  • SpringBoot配置文件加載方法詳細(xì)講解

    SpringBoot配置文件加載方法詳細(xì)講解

    springboot默認(rèn)讀取的配置文件名字是:“application.properties”和“application.yml”,默認(rèn)讀取四個(gè)位置的文件:根目錄下、根目錄的config目錄下、classpath目錄下、classpath目錄里的config目錄下
    2022-10-10
  • Mybatis如何根據(jù)List批量查詢List結(jié)果

    Mybatis如何根據(jù)List批量查詢List結(jié)果

    這篇文章主要介紹了Mybatis如何根據(jù)List批量查詢List結(jié)果,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Spring的Bean容器介紹

    Spring的Bean容器介紹

    今天小編就為大家分享一篇關(guān)于Spring的Bean容器介紹,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 深入解析Java編程中final關(guān)鍵字的作用

    深入解析Java編程中final關(guān)鍵字的作用

    final關(guān)鍵字正如其字面意思一樣,意味著最后,比如被final修飾后類不能集成、變量不能被再賦值等,以下我們就來深入解析Java編程中final關(guān)鍵字的作用:
    2016-06-06
  • JAVA位運(yùn)算的知識點(diǎn)總結(jié)

    JAVA位運(yùn)算的知識點(diǎn)總結(jié)

    在本篇文章里小編給大家整理的是關(guān)于JAVA有關(guān)位運(yùn)算的全套梳理,需要的朋友們可以參考學(xué)習(xí)下。
    2020-03-03
  • 基于java中cookie和session的比較

    基于java中cookie和session的比較

    下面小編就為大家?guī)硪黄趈ava中cookie和session的比較。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • 你知道JVM中GC?Root對象有哪些嗎

    你知道JVM中GC?Root對象有哪些嗎

    這篇文章主要介紹了你知道JVM中GC?Root對象有哪些,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評論