国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > Java > 正文

Java線程Dump分析工具jstack解析及使用場(chǎng)景

2024-07-13 10:15:47
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

jstack用于打印出給定的java進(jìn)程ID或core file或遠(yuǎn)程調(diào)試服務(wù)的Java堆棧信息,如果是在64位機(jī)器上,需要指定選項(xiàng)"-J-d64",Windows的jstack使用方式只支持以下的這種方式:

jstack [-l][F] pid

如果java程序崩潰生成core文件,jstack工具可以用來(lái)獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發(fā)生問(wèn)題。另外,jstack工具還可以附屬到正在運(yùn)行的java程序中,看到當(dāng)時(shí)運(yùn)行的java程序的java stack和native stack的信息, 如果現(xiàn)在運(yùn)行的java程序呈現(xiàn)hung的狀態(tài),jstack是非常有用的。進(jìn)程處于hung死狀態(tài)可以用-F強(qiáng)制打出stack。

dump 文件里,值得關(guān)注的線程狀態(tài)有:

死鎖,Deadlock(重點(diǎn)關(guān)注)

執(zhí)行中,Runnable

等待資源,Waiting on condition(重點(diǎn)關(guān)注)

等待獲取監(jiān)視器,Waiting on monitor entry(重點(diǎn)關(guān)注)

暫停,Suspended

對(duì)象等待中,Object.wait() 或 TIMED_WAITING

阻塞,Blocked(重點(diǎn)關(guān)注)

停止,Parked

在摘了另一篇博客的三種場(chǎng)景:

實(shí)例一:Waiting to lock 和 Blocked

"RMI TCP Connection(267865)-172.16.5.25" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting for monitor entry [0x00007fd4f8684000]  java.lang.Thread.State: BLOCKED (on object monitor)at org.apache.log4j.Category.callAppenders(Category.java:201)- waiting to lock <0x00000000acf4d0c0> (a org.apache.log4j.Logger)at org.apache.log4j.Category.forcedLog(Category.java:388)at org.apache.log4j.Category.log(Category.java:853)at org.apache.commons.logging.impl.Log4JLogger.warn(Log4JLogger.java:234)at com.tuan.core.common.lang.cache.remote.SpyMemcachedClient.get(SpyMemcachedClient.java:110)

說(shuō)明:

1)線程狀態(tài)是 Blocked,阻塞狀態(tài)。說(shuō)明線程等待資源超時(shí)!

2)“ waiting to lock <0x00000000acf4d0c0>”指,線程在等待給這個(gè) 0x00000000acf4d0c0 地址上鎖(英文可描述為:trying to obtain 0x00000000acf4d0c0 lock)。

3)在 dump 日志里查找字符串 0x00000000acf4d0c0,發(fā)現(xiàn)有大量線程都在等待給這個(gè)地址上鎖。如果能在日志里找到誰(shuí)獲得了這個(gè)鎖(如locked < 0x00000000acf4d0c0 >),就可以順藤摸瓜了。

4)“waiting for monitor entry”說(shuō)明此線程通過(guò) synchronized(obj) {……} 申請(qǐng)進(jìn)入了臨界區(qū),從而進(jìn)入了下圖1中的“Entry Set”隊(duì)列,但該 obj 對(duì)應(yīng)的 monitor 被其他線程擁有,所以本線程在 Entry Set 隊(duì)列中等待。

5)第一行里,"RMI TCP Connection(267865)-172.16.5.25"是 Thread Name 。tid指Java Thread id。nid指native線程的id。prio是線程優(yōu)先級(jí)。[0x00007fd4f8684000]是線程棧起始地址。

實(shí)例二:Waiting on condition 和 TIMED_WAITING

"RMI TCP Connection(idle)" daemon prio=10 tid=0x00007fd50834e800 nid=0x56b2 waiting on condition [0x00007fd4f1a59000]  java.lang.Thread.State: TIMED_WAITING (parking)at sun.misc.Unsafe.park(Native Method)- parking to wait for <0x00000000acd84de8> (a java.util.concurrent.SynchronousQueue$TransferStack)at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)at java.lang.Thread.run(Thread.java:662)

說(shuō)明:

1)“TIMED_WAITING (parking)”中的 timed_waiting 指等待狀態(tài),但這里指定了時(shí)間,到達(dá)指定的時(shí)間后自動(dòng)退出等待狀態(tài);parking指線程處于掛起中。

2)“waiting on condition”需要與堆棧中的“parking to wait for <0x00000000acd84de8> (a java.util.concurrent.SynchronousQueue$TransferStack)”結(jié)合來(lái)看。首先,本線程肯定是在等待某個(gè)條件的發(fā)生,來(lái)把自己?jiǎn)拘选F浯危琒ynchronousQueue 并不是一個(gè)隊(duì)列,只是線程之間移交信息的機(jī)制,當(dāng)我們把一個(gè)元素放入到 SynchronousQueue 中時(shí)必須有另一個(gè)線程正在等待接受移交的任務(wù),因此這就是本線程在等待的條件。

3)別的就看不出來(lái)了。

實(shí)例三:in Obejct.wait() 和 TIMED_WAITING

"RMI RenewClean-[172.16.5.19:28475]" daemon prio=10 tid=0x0000000041428800 nid=0xb09 in Object.wait() [0x00007f34f4bd0000]  java.lang.Thread.State: TIMED_WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x00000000aa672478> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)- locked <0x00000000aa672478> (a java.lang.ref.ReferenceQueue$Lock)at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:516)at java.lang.Thread.run(Thread.java:662)

說(shuō)明:

1)“TIMED_WAITING (on object monitor)”,對(duì)于本例而言,是因?yàn)楸揪€程調(diào)用了 java.lang.Object.wait(long timeout) 而進(jìn)入等待狀態(tài)。

2)“Wait Set”中等待的線程狀態(tài)就是“ in Object.wait() ”。當(dāng)線程獲得了 Monitor,進(jìn)入了臨界區(qū)之后,如果發(fā)現(xiàn)線程繼續(xù)運(yùn)行的條件沒(méi)有滿足,它則調(diào)用對(duì)象(一般就是被 synchronized 的對(duì)象)的 wait() 方法,放棄了 Monitor,進(jìn)入 “Wait Set”隊(duì)列。只有當(dāng)別的線程在該對(duì)象上調(diào)用了 notify() 或者 notifyAll() ,“ Wait Set”隊(duì)列中線程才得到機(jī)會(huì)去競(jìng)爭(zhēng),但是只有一個(gè)線程獲得對(duì)象的 Monitor,恢復(fù)到運(yùn)行態(tài)。

3)RMI RenewClean 是 DGCClient 的一部分。DGC 指的是 Distributed GC,即分布式垃圾回收。

4)請(qǐng)注意,是先 locked <0x00000000aa672478>,后 waiting on <0x00000000aa672478>,之所以先鎖再等同一個(gè)對(duì)象,請(qǐng)看下面它的代碼實(shí)現(xiàn):

static private class Lock { };private Lock lock = new Lock();public Reference<? extends T> remove(long timeout){  synchronized (lock) {    Reference<? extends T> r = reallyPoll();    if (r != null) return r;    for (;;) {      lock.wait(timeout);      r = reallyPoll();      ……    }}

即,線程的執(zhí)行中,先用 synchronized 獲得了這個(gè)對(duì)象的 Monitor(對(duì)應(yīng)于 locked <0x00000000aa672478> );當(dāng)執(zhí)行到 lock.wait(timeout);,線程就放棄了 Monitor 的所有權(quán),進(jìn)入“Wait Set”隊(duì)列(對(duì)應(yīng)于 waiting on <0x00000000aa672478> )。

5)從堆棧信息看,是正在清理 remote references to remote objects ,引用的租約到了,分布式垃圾回收在逐一清理呢。

總結(jié)

以上就是本文關(guān)于Java線程Dump分析工具jstack解析及使用場(chǎng)景的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JAVA教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 定兴县| 定州市| 吴堡县| 攀枝花市| 驻马店市| 遵化市| 金门县| 泰来县| 壶关县| 秭归县| 南郑县| 安徽省| 巧家县| 宁晋县| 连云港市| 东乌| 伊川县| 天台县| 长宁区| 小金县| 重庆市| 孟村| 济阳县| 平山县| 六枝特区| 阳信县| 鹰潭市| 平谷区| 宁明县| 辽阳县| 新兴县| 泌阳县| 息烽县| 监利县| 济宁市| 东辽县| 昌都县| 云安县| 酒泉市| 枞阳县| 永登县|