JVM 線程dump 導(dǎo)出和分析

前言

  • 線程dump是非常有用的診斷java應(yīng)用問題的工具臼寄,每一個(gè)java虛擬機(jī)都有及時(shí)生成顯示所有線程在某一點(diǎn)狀態(tài)的線程dump的能力。雖然各個(gè)java虛擬機(jī)線程dump打印輸出格式上略微有一些不同溜宽,但是線程dump出來的信息包含線程基本信息吉拳;線程的運(yùn)行狀態(tài)、標(biāo)識(shí)和調(diào)用的堆棧适揉;調(diào)用的堆棧包含完整的類名留攒,所執(zhí)行的方法煤惩,如果可能的話還有源代碼的行數(shù)。

  • JVM中的許多問題都可以使用線程dump文件來進(jìn)行診斷炼邀,其中比較典型的包括線程阻塞魄揉,CPU使用率過高,JVM Crash拭宁,堆內(nèi)存不足和類裝載等問題洛退。

導(dǎo)出

1、查詢java進(jìn)程pid

  • 使用jps [-l]命令查看本機(jī)所有java進(jìn)程pid
jps [-l]
image.png

2杰标、使用top查看目前正在運(yùn)行的進(jìn)程使用系統(tǒng)資源情況

top
image.png

image.png

當(dāng)前占用cpu最高26.5%的進(jìn)程為27796的java程序

3兵怯、導(dǎo)出指定進(jìn)程pid所有線程信息

1)將所有線程信息輸入到指定文件中

jstack [-l] pid > xxx.log
image.png

2)-F (當(dāng)'jstack [-l] pid'沒有響應(yīng),強(qiáng)制導(dǎo)出堆棧dump)

jstack -F [-m] [-l] pid >xxx.log

4腔剂、分析

線程狀態(tài)介紹
  • 死鎖摇零,Deadlock(重點(diǎn)關(guān)注) :一般指多個(gè)線程調(diào)用間,進(jìn)入相互資源占用桶蝎,導(dǎo)致一直等待無法釋放的情況驻仅。

  • 執(zhí)行中,Runnable :一般指該線程正在執(zhí)行狀態(tài)中登渣,該線程占用了資源噪服,正在處理某個(gè)請(qǐng)求,有可能正在傳遞SQL到數(shù)據(jù)庫執(zhí)行胜茧,有可能在對(duì)某個(gè)文件操作粘优,有可能進(jìn)行數(shù)據(jù)類型等轉(zhuǎn)換。

  • 等待資源呻顽,Waiting on condition(重點(diǎn)關(guān)注) :等待資源雹顺,或等待某個(gè)條件的發(fā)生。具體原因需結(jié)合 stacktrace來分析廊遍。
    ??1嬉愧、如果堆棧信息明確是應(yīng)用代碼,則證明該線程正在等待資源喉前。一般是大量讀取某資源没酣,且該資源采用了資源鎖的情況下,線程進(jìn)入等待狀態(tài)卵迂,等待資源的讀取裕便。
    又或者,正在等待其他線程的執(zhí)行等见咒。
    ??2偿衰、如果發(fā)現(xiàn)有大量的線程都在處在 Wait on condition,從線程 stack看,正等待網(wǎng)絡(luò)讀寫下翎,這可能是一個(gè)網(wǎng)絡(luò)瓶頸的征兆囱嫩。因?yàn)榫W(wǎng)絡(luò)阻塞導(dǎo)致線程無法執(zhí)行。
    ????2.1漏设、一種情況是網(wǎng)絡(luò)非常忙墨闲,幾乎消耗了所有的帶寬,仍然有大量數(shù)據(jù)等待網(wǎng)絡(luò)讀寫郑口;
    ????2.2鸳碧、另一種情況也可能是網(wǎng)絡(luò)空閑,但由于路由等問題犬性,導(dǎo)致包無法正常的到達(dá)瞻离。
    ??3、另外一種出現(xiàn) Wait on condition的常見情況是該線程在 sleep乒裆,等待 sleep的時(shí)間到了時(shí)候而涉,將被喚醒娄帖。

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

  • 對(duì)象等待中,Object.wait() 或 TIMED_WAITING
    ??Waiting for monitor entry 和 in Object.wait():
    ??Monitor(Monitor的深入理解傳送門)是 Java中用以實(shí)現(xiàn)線程之間的互斥與協(xié)作的主要手段威酒,它可以看成是對(duì)象或者 Class的鎖凶硅。每一個(gè)對(duì)象都有尝苇,也僅有一個(gè) monitor雳旅。
    ??從下圖中可以看出,每個(gè) Monitor在某個(gè)時(shí)刻杆怕,只能被一個(gè)線程擁有族购,該線程就是 “Active Thread”,而其它線程都是 “Waiting Thread”陵珍,分別在兩個(gè)隊(duì)列 “ Entry Set”和 “Wait Set”里面等候寝杖。
    ??在 “Entry Set”中等待的線程狀態(tài)是 “Waiting for monitor entry”,而在 “Wait Set”中等待的線程狀態(tài)是 “in Object.wait()”

    Java Monitor

  • 暫停互纯,Suspended
  • 阻塞瑟幕,Blocked(重點(diǎn)關(guān)注) :是指當(dāng)前線程執(zhí)行過程中,所需要的資源長時(shí)間等待卻一直未能獲取到伟姐,被容器的線程管理器標(biāo)識(shí)為阻塞狀態(tài)收苏,可以理解為等待資源超時(shí)的線程。
  • 停止愤兵,Parked
jvm_27796.log展示
image.png
stack trace實(shí)例分析
"consumer_redirectUrl_topic_jmq206_1546013217302" daemon prio=10 tid=0x00007f1bf03f6800 nid=0x693e waiting on condition [0x00007f1b38388000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000f76e21a0> (a java.util.concurrent.CountDownLatch$Sync)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1033)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1326)
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:282)
    at com.jd.jmq.common.network.netty.ResponseFuture.await(ResponseFuture.java:133)
    at com.jd.jmq.common.network.netty.NettyTransport.sync(NettyTransport.java:241)
    at com.jd.jmq.common.network.netty.failover.FailoverNettyClient.sync(FailoverNettyClient.java:94)
    at com.jd.jmq.client.consumer.GroupConsumer.pull(GroupConsumer.java:246)
    at com.jd.jmq.client.consumer.GroupConsumer$QueueConsumer.run(GroupConsumer.java:445)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - None
  • 線程名:consumer_redirectUrl_topic_jmq206_1546013217302
  • 線程優(yōu)先級(jí):prio=10
  • java線程的identifier:tid=0x00007f1bf03f6800
  • native線程的identifier:nid=0x693e
  • 線程的狀態(tài):waiting on condition [0x00007f1b38388000]
    java.lang.Thread.State: TIMED_WAITING (parking)
  • 線程棧起始地址:[0x00007f1b38388000]
找出某進(jìn)程中要分析的線程ID
top -H -p <pid>
image.png

image.png
將線程ID轉(zhuǎn)換為16進(jìn)制后,在線程dump文件中搜索相關(guān)信息

例如:27840==》6cc0


image.png
"System_Clock" daemon prio=10 tid=0x00007f1c2cbc6800 nid=0x6cc0 runnable [0x00007f1c24872000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000c0c9d918> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - None
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末排吴,一起剝皮案震驚了整個(gè)濱河市秆乳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖屹堰,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肛冶,死亡現(xiàn)場離奇詭異,居然都是意外死亡扯键,警方通過查閱死者的電腦和手機(jī)睦袖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荣刑,“玉大人馅笙,你說我怎么就攤上這事±骺鳎” “怎么了董习?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爱只。 經(jīng)常有香客問我皿淋,道長,這世上最難降的妖魔是什么恬试? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任窝趣,我火速辦了婚禮,結(jié)果婚禮上训柴,老公的妹妹穿的比我還像新娘高帖。我一直安慰自己,他們只是感情好畦粮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布散址。 她就那樣靜靜地躺著,像睡著了一般宣赔。 火紅的嫁衣襯著肌膚如雪预麸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天儒将,我揣著相機(jī)與錄音吏祸,去河邊找鬼。 笑死钩蚊,一個(gè)胖子當(dāng)著我的面吹牛贡翘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砰逻,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼鸣驱,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了蝠咆?” 一聲冷哼從身側(cè)響起踊东,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤北滥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后闸翅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體再芋,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年坚冀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了济赎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡记某,死狀恐怖司训,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辙纬,我是刑警寧澤豁遭,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站贺拣,受9級(jí)特大地震影響蓖谢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜譬涡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一闪幽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涡匀,春花似錦盯腌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至舌劳,卻和暖如春帚湘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背甚淡。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工大诸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贯卦。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓资柔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撵割。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贿堰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • jstack用于打印出給定的java進(jìn)程ID或core file或遠(yuǎn)程調(diào)試服務(wù)的Java堆棧信息,如果是在64位機(jī)...
    sherlock_6981閱讀 921評(píng)論 0 0
  • http://jameswxx.iteye.com/blog/1041173 jstack命令的語法格式: jst...
    sherlock_6981閱讀 513評(píng)論 0 1
  • 一睁枕、top(Linux命令) 執(zhí)行top命令: (查看進(jìn)程15477的詳細(xì)情況官边,下文用到) 系統(tǒng)信息(前五行): ...
    java菜閱讀 1,137評(píng)論 0 1
  • jstack命令的用法為jstack pid jstack在jdk/bin的目錄下 在實(shí)際運(yùn)行中沸手,建議產(chǎn)生3次以上...
    better0812閱讀 8,826評(píng)論 0 0
  • 一外遇、Thread Dump日志的線程信息 "resin-22129"線程名稱:如果使用 java.lang.Thr...
    倪寶華閱讀 6,975評(píng)論 1 0