大致思路:
一、導(dǎo)出thread dump惰说、heap dump文件 (方式多種)
? ? 1.通過(guò)jvisualvm工具添加jmx連接(前提線上容器開(kāi)啟jmx)磨德,直接點(diǎn)擊堆Dump、線程Dump操作助被。
? ? 2.通過(guò)連接服務(wù)器剖张,執(zhí)行命令jstack、jmap進(jìn)行導(dǎo)出堆Dump揩环、線程Dump文件搔弄。
? ? %可通過(guò)jvisualvm工具導(dǎo)入堆Dump文件分析%
二、分析thread dump:關(guān)注線程狀態(tài)
????1.死鎖丰滑,Deadlock(重點(diǎn)關(guān)注)?
????2.執(zhí)行中顾犹,Runnable? ?
????3.等待資源,Waiting on condition(重點(diǎn)關(guān)注)
????4.等待獲取監(jiān)視器褒墨,Waiting on monitor entry(重點(diǎn)關(guān)注)
????5.暫停炫刷,Suspended
????6.對(duì)象等待中,Object.wait() 或 TIMED_WAITING
????7.阻塞郁妈,Blocked(重點(diǎn)關(guān)注)??
????8.停止浑玛,Parked
????**.Deadlock:死鎖線程,一般指多個(gè)線程調(diào)用間噩咪,進(jìn)入相互資源占用顾彰,導(dǎo)致一直等待無(wú)法釋放的情況极阅。
????**.Runnable:一般指該線程正在執(zhí)行狀態(tài)中,該線程占用了資源涨享,正在處理某個(gè)請(qǐng)求筋搏,有可能正在傳遞SQL到數(shù)據(jù)庫(kù)執(zhí)行,有可能在對(duì)某個(gè)文件操作厕隧,有可能進(jìn)行數(shù)據(jù)類型等轉(zhuǎn)換奔脐。
????**.Waiting on condition:等待資源,或等待某個(gè)條件的發(fā)生吁讨。具體原因需結(jié)合 stacktrace來(lái)分析髓迎。如果堆棧信息明確是應(yīng)用代碼,則證明該線程正在等待資源挡爵。一般是大量讀取某資源竖般,且該資源采用了資源鎖的情況下,線程進(jìn)入等待狀態(tài)茶鹃,等待資源的讀取涣雕。又或者,正在等待其他線程的執(zhí)行等闭翩。如果發(fā)現(xiàn)有大量的線程都在處在 Wait on condition挣郭,從線程 stack看,正等待網(wǎng)絡(luò)讀寫(xiě)疗韵,這可能是一個(gè)網(wǎng)絡(luò)瓶頸的征兆兑障。因?yàn)榫W(wǎng)絡(luò)阻塞導(dǎo)致線程無(wú)法執(zhí)行。一種情況是網(wǎng)絡(luò)非常忙蕉汪,幾乎消耗了所有的帶寬流译,仍然有大量數(shù)據(jù)等待網(wǎng)絡(luò)讀寫(xiě);另一種情況也可能是網(wǎng)絡(luò)空閑者疤,但由于路由等問(wèn)題福澡,導(dǎo)致包無(wú)法正常的到達(dá)。另外一種出現(xiàn) Wait on condition的常見(jiàn)情況是該線程在 sleep驹马,等待 sleep的時(shí)間到了時(shí)候革砸,將被喚醒。
**.Blocked:線程阻塞糯累,是指當(dāng)前線程執(zhí)行過(guò)程中算利,所需要的資源長(zhǎng)時(shí)間等待卻一直未能獲取到,被容器的線程管理器標(biāo)識(shí)為阻塞狀態(tài)泳姐,可以理解為等待資源超時(shí)的線程效拭。
????**.Waiting for monitor entry 和 in Object.wait():Monitor是 Java中用以實(shí)現(xiàn)線程之間的互斥與協(xié)作的主要手段,它可以看成是對(duì)象或者 Class的鎖。每一個(gè)對(duì)象都有允耿,也僅有一個(gè) monitor借笙。從下圖1中可以看出,每個(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()”。
三、找到最耗CPU線程
? ? ?1.執(zhí)行top -c蛙酪,顯示進(jìn)程運(yùn)行信息列表二蓝,進(jìn)程按照CPU使用率排序。
? ? ?2.執(zhí)行top -Hp ${pid}朦蕴,顯示一個(gè)進(jìn)程的線程運(yùn)行信息列表篮条,線程按照CPU使用率排序
? ? ?3.將線程PID轉(zhuǎn)化為16進(jìn)制(printf "0x%x\n" ${pid})
? ? ?4.找到線程在干嘛(jstack ${pid}| grep 0x658 -A 20)
? ? ? ?根據(jù)jstack的輸出,結(jié)合源碼很容易就可以發(fā)現(xiàn)問(wèn)題: