1. 經過top和jstack確定哪些線程耗盡了CPU
背景
有時,線上集群load會突然飆升,無法響應正常請求。
那麼引起load飆升的線程究竟在做什麼?哪些線程霸佔了CPU?可以通過top和jstack命令進行定位。
2. 定位步驟
1. 使用終端1進入目標機器,執行top命令,默認是進程視圖,其中PID是進程號,截圖如下:
在這里,我們只能看到java進程佔用CPU達到115%,那麼究竟是那些線程非常耗CPU呢?
2. 由於我們要看到線程,在終端1,按下「H」鍵或者「shift+h」,top視圖會切換到線程視圖,其中PID是線程號,截圖如下:
可以發現紅框內的線程的CPU使用率非常高,佔用CPU時間達到1秒左右,顯然不正常,但是這些線程在做什麼?
3.
打開終端2,使用jstack命令輸出這一時刻的線程棧,保存到文件,命名為jstack.log。注意:輸出線程棧和保存top命令快照盡量同時進行。
4. 由於jstack.log文件記錄的線程ID是16進制,需要將top命令展示的線程號轉換為16進制,以15100為例,在linux下輸入命令:printf 0x%x 15100,得到15100的十六進制為0x3afc
5. 在jstack.log中搜索0x3afc關鍵字,可以清晰看到該線程在做刷新地址列表,如下圖:
3. 總結
以前碰到集群load飆升時,有時會束手無策,不知從何查起。以後再發生類似問題時,可以使用這個方法,看下究竟是那些線程在長時間佔用CPU,盡快定位問題和解決問題。
2. openjdk中沒有jstack怎麼辦
首先在cmd下輸入
jps -l -m
查詢pid
例子:
C:\herong>\Progra~1\java\jdk1.8.0\bin\jps -l -m
3296 LongSleep
2224 sun.tools.jps.Jps -l -m
C:\herong>\Progra~1\java\jdk1.8.0\bin\jstack 3296
3. python中有沒有像java中的jstack命令
沒有像jstack那麼方便直接用的東西,一般來說有幾個方案:
IDE: 用諸如 PyCharm, Eclpise with Pydev 的工具調試,覺得掛起的時候暫停並檢查各個調用棧。
GDB: 優點是可以調試到native extension,缺點也很明顯,需要在編譯Python的時候加上Debug Symbols,默認這個是沒有的。簡單的說就是功能強大但是配得麻煩。
pdb:適合下斷點...
pudb: 改下代碼,在程序入口import pudb; pudb.set_interrupt_handler(),在運行的時候就可以Ctrl-C進入到互動式調試環境,易用性還好吧。
擼一個singal handler用於列印所有棧信息,參考 celery 實現的 install_cry_handler,或者看看 signalhandler,這個在 Python 3.3 自帶了。
4. 如何使用jstack分析線程狀態
1、上圖中可以看出pid為23344的java進程佔用了較多的cpu資源; 2、通過top -Hp 23344可以查看該進程下各個線程的cpu使用情況; 上圖中可以看出pid為25077的線程佔了較多的cpu資源,利用jstack命令可以繼續查看該線程當前的堆棧狀態。 jstack命令...
5. 通過top和jstack確定哪些線程耗盡了CPU這些線程在做什麼
背景有時,線上集群load會突然飆升,無法響應正常請求。那麼引起load飆升的線程究竟在做什麼?哪些線程霸佔了CPU?可以通過top和jstack命令進行定位。2. 定位步驟1. 使用終端1進入目標機器,執行top命令,默認是進程視圖,其中PID是進程號,截圖如下:在這里,我們只能看到java進程佔用CPU達到115%,那麼究竟是那些線程非常耗CPU呢?2. 由於我們要看到線程,在終端1,按下「H」鍵或者「shift+h」,top視圖會切換到線程視圖,其中PID是線程號,截圖如下:可以發現紅框內的線程的CPU使用率非常高,佔用CPU時間達到1秒左右,顯然不正常,但是這些線程在做什麼?3. 打開終端2,使用jstack命令輸出這一時刻的線程棧,保存到文件,命名為jstack.log。注意:輸出線程棧和保存top命令快照盡量同時進行通過top和jstack確定哪些線程耗盡了CPU?這些線程在做什麼
6. jstack 分析出線程id 如何找到進程嗎
jstack 分析出線程id 如何找到進程
jstack用於列印出給定的java進程ID或core file或遠程調試服務的Java堆棧信息。
如果是在64位機器上,需要指定選項"-J-d64",Windows的jstack使用方式只支持以下的這種方式:jstack [-l] pid
如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發生問題。
另外,jstack工具還可以附屬到正在運行的java程序中,看到當時運行的java程序的java stack和native stack的信息, 如果現在運行的java程序呈現hung的狀態,jstack是非常有用的。
需要注意的問題:
l 不同的 JAVA虛機的線程 DUMP的創建方法和文件格式是不一樣的,不同的 JVM版本, mp信息也有差別。
l 在實際運行中,往往一次 mp的信息,還不足以確認問題。建議產生三次 mp信息,如果每次 mp都指向同一個問題,我們才確定問題的典型性。
2、命令格式
$jstack [ option ] pid
$jstack [ option ] executable core
$jstack [ option ] [server-id@]remote-hostname-or-IP
參數說明:
pid: java應用程序的進程號,一般可以通過jps來獲得;
executable:產生core mp的java可執行程序;
core:列印出的core文件;
remote-hostname-or-ip:遠程debug伺服器的名稱或IP;
server-id: 唯一id,假如一台主機上多個遠程debug服務;
示例:
$jstack –l 23561
線程分析:
一般情況下,通過jstack輸出的線程信息主要包括:jvm自身線程、用戶線程等。其中jvm線程會在jvm啟動時就會存在。對於用戶線程則是在用戶訪問時才會生成。
7. 虛擬機中不能使用jstack命令嗎
找到CPU利用率持續比較高的進程,獲取進程號,此處PID為3036
命令:
top
找到上述進程中,CPU利用率比較高的線程號TID(十進制數),此處為3046
命令:
將獲取的線程號(十進制數)轉換成十六進制,此處為0xb46
6
查看進程PID為3036中
nid為0xb46的線程信息。
8. 怎麼jstack命令mp線程信息
一般情況下,通過jstack輸出的線程信息主要包括:jvm自身線程、用戶線程等。其中jvm線程會在jvm啟動時就會存在。對於用戶線程則是在用戶訪問時才會生成。
l jvm線程:
在線程中,有一些 JVM內部的後台線程,來執行譬如垃圾回收,或者低內存的檢測等等任務,這些線程往往在JVM初始化的時候就存在
9. 怎樣使用jstack診斷Java應用程序故障
首先讓我們來了解一下jstack這個命令的作用,jstack
是一個可以返回在應用程序上運行的各種各樣線程的一個完整轉儲的實用程序,您可以使用它查明問題。jstack [-l]
<pid>,jpid可以通過使用jps命令來查看當前Java程序的jpid值,-l是可選參數,它可以顯示線程阻塞/死鎖情況。
Java代碼
/**
* 死鎖例子
* @author crane.ding
* @since 2011-3-20
*/
public class DeadLock {
public static void main(String[] args) {
final Object obj_1 = new Object(), obj_2 = new Object();
Thread t1 = new Thread("t1"){
@Override
public void run() {
synchronized (obj_1) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
synchronized (obj_2) {
System.out.println("thread t1 done.");
}
}
}
};
Thread t2 = new Thread("t2"){
@Override
public void run() {
synchronized (obj_2) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
synchronized (obj_1) {
System.out.println("thread t2 done.");
}
}
}
};
t1.start();
t2.start();
}
}
以上DeadLock類是一個死鎖的例子,假使在我們不知情的情況下,運行DeadLock後,發現等了N久都沒有在屏幕列印線程完成信息。這個時候我們就可以使用jps查看該程序的jpid值和使用jstack來生產堆棧結果問題。
Linux代碼
$ java -cp deadlock.jar DeadLock &
$
Linux代碼
$ jps
3076 Jps
448 DeadLock
$ jstack -l 448 > deadlock.jstack
結果文件deadlock.jstack內容如下:
Xml代碼
2011-03-20 23:05:20
Full thread mp Java HotSpot(TM) Client VM (19.1-b02 mixed mode, sharing):
"DestroyJavaVM" prio=6 tid=0x00316800 nid=0x9fc waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"t2" prio=6 tid=0x02bcf000 nid=0xc70 waiting for monitor entry [0x02f6f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.demo.DeadLock$2.run(DeadLock.java:40)
- waiting to lock <0x22a297a8> (a java.lang.Object)
- locked <0x22a297b0> (a java.lang.Object)
Locked ownable synchronizers:
- None
"t1" prio=6 tid=0x02bce400 nid=0xba0 waiting for monitor entry [0x02f1f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.demo.DeadLock$1.run(DeadLock.java:25)
- waiting to lock <0x22a297b0> (a java.lang.Object)
- locked <0x22a297a8> (a java.lang.Object)
Locked ownable synchronizers:
- None
"Low Memory Detector" daemon prio=6 tid=0x02bb9400 nid=0xa6c runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"CompilerThread0" daemon prio=10 tid=0x02bb2800 nid=0xcb8 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Attach Listener" daemon prio=10 tid=0x02bb1000 nid=0x7f4 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Signal Dispatcher" daemon prio=10 tid=0x02bd2800 nid=0xd80 runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" daemon prio=8 tid=0x02bab000 nid=0xe1c in Object.wait() [0x02d3f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
Locked ownable synchronizers:
- None
"Reference Handler" daemon prio=10 tid=0x02ba6800 nid=0xbe0 in Object.wait() [0x02cef000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x229e1048> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x229e1048> (a java.lang.ref.Reference$Lock)
Locked ownable synchronizers:
- None
"VM Thread" prio=10 tid=0x02b6a400 nid=0x568 runnable
"VM Periodic Task Thread" prio=10 tid=0x02bc8400 nid=0x75c waiting on condition
JNI global references: 878
Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x02baaeec (object 0x22a297a8, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x02baa2bc (object 0x22a297b0, a java.lang.Object),
which is held by "t2"
Java stack information for the threads listed above:
===================================================
"t2":
at com.demo.DeadLock$2.run(DeadLock.java:40)
- waiting to lock <0x22a297a8> (a java.lang.Object)
- locked <0x22a297b0> (a java.lang.Object)
"t1":
at com.demo.DeadLock$1.run(DeadLock.java:25)
- waiting to lock <0x22a297b0> (a java.lang.Object)
- locked <0x22a297a8> (a java.lang.Object)
Found 1 deadlock.
從這個結果文件我們一看到發現了一個死鎖,具體是線程t2在等待線程t1,而線程t1在等待線程t2造成的,同時也記錄了線程的堆棧和代碼行數,通過這個堆棧和行數我們就可以去檢查對應的代碼塊,從而發現問題和解決問題。
10. 如何使用 jstack 分析線程狀態
1、上圖中可以看出pid為23344的java進程佔用了較多的cpu資源;
2、通過top -Hp 23344可以查看該進程下各個線程的cpu使用情況;
上圖中可以看出pid為25077的線程佔了較多的cpu資源,利用jstack命令可以繼續查看該線程當前的堆棧狀態。
jstack命令
通過top命令定位到cpu佔用率較高的線程之後,繼續使用jstack pid命令查看當前java進程的堆棧狀態
jstack命令生成的thread mp信息包含了JVM中所有存活的線程,為了分析指定線程,必須找出對應線程的調用棧,應該如何找?
在top命令中,已經獲取到了佔用cpu資源較高的線程pid,將該pid轉成16進制的值,在thread mp中每個線程都有一個nid,找到對應的nid即可;隔段時間再執行一次stack命令獲取thread mp,區分兩份mp是否有差別,在nid=0x246c的線程調用棧中,發現該線程一直在執行JstackCase類第33行的calculate方法,得到這個信息,就可以檢查對應的代碼是否有問題。
通過thread mp分析線程狀態