解決線程異常WAITING(parking)問題
線程異常WAITING(parking)
現(xiàn)象
在項目中線程數(shù)量持續(xù)增長,且基本無法回收關閉,線程數(shù)量一直累積達到幾萬,影響CPU開銷和性能,導致服務器卡死,連接上服務器后輸入指令提示“無可分配內存”。
查找原因
1.通過ps -eLf|grep '容器名'|wc -l命令找到項目的所占的線程數(shù)異常龐大,通過top -p pid H也發(fā)現(xiàn)該進程下大量占用資源的線程。
進入容器內查看堆棧信息。
2.通過**jstack -l pid| grep 'java.lang.Thread.State'**發(fā)現(xiàn)項目的線程狀態(tài)大多數(shù)都是WAITING(parking)狀態(tài)
分析是線程一直處于等待狀態(tài)一直在占用,造成GC無法執(zhí)行,且新請求進來時造成線程占用累計
3.打印當前JVM快照:
**jstack 7 > /opt/test.dump**
查看快照定位原因:
分析原因
在我的業(yè)務中每次處理請求時都會創(chuàng)建一個線程池去多鏈路執(zhí)行不同的流程,但是執(zhí)行完畢后沒有使用shutdown()關閉這個線程池對象
這樣線程池仍會通過take方法去取等待隊列中是否還有未完成的線程任務,等待隊列為空時將會一直等待
這樣就導致大量的線程hung在這里了(基本是只要方法被調一次,就會產生一個hung住的線程),所以有大量空線程一直占用,造成嚴重的線程泄漏
總結
在自定義線程池且未交給spring容器管理時,使用完畢的線程池一定要執(zhí)行shutDown()手動關閉線程池,這是編程上的疏忽。
找到原因后感覺問題很簡單,但是查找過程中還是碰壁不少,找過幾次都沒有找到最終原因。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
java實現(xiàn)系統(tǒng)捕獲異常發(fā)送郵件案例
這篇文章主要為大家詳細介紹了java實現(xiàn)系統(tǒng)捕獲異常發(fā)送郵件案例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11