解決線程異常WAITING(parking)問題
線程異常WAITING(parking)
現(xiàn)象
在項(xiàng)目中線程數(shù)量持續(xù)增長(zhǎng),且基本無法回收關(guān)閉,線程數(shù)量一直累積達(dá)到幾萬,影響CPU開銷和性能,導(dǎo)致服務(wù)器卡死,連接上服務(wù)器后輸入指令提示“無可分配內(nèi)存”。
查找原因
1.通過ps -eLf|grep '容器名'|wc -l命令找到項(xiàng)目的所占的線程數(shù)異常龐大,通過top -p pid H也發(fā)現(xiàn)該進(jìn)程下大量占用資源的線程。
進(jìn)入容器內(nèi)查看堆棧信息。
2.通過**jstack -l pid| grep 'java.lang.Thread.State'**發(fā)現(xiàn)項(xiàng)目的線程狀態(tài)大多數(shù)都是WAITING(parking)狀態(tài)
分析是線程一直處于等待狀態(tài)一直在占用,造成GC無法執(zhí)行,且新請(qǐng)求進(jìn)來時(shí)造成線程占用累計(jì)
3.打印當(dāng)前JVM快照:
**jstack 7 > /opt/test.dump**
查看快照定位原因:
分析原因
在我的業(yè)務(wù)中每次處理請(qǐng)求時(shí)都會(huì)創(chuàng)建一個(gè)線程池去多鏈路執(zhí)行不同的流程,但是執(zhí)行完畢后沒有使用shutdown()關(guān)閉這個(gè)線程池對(duì)象
這樣線程池仍會(huì)通過take方法去取等待隊(duì)列中是否還有未完成的線程任務(wù),等待隊(duì)列為空時(shí)將會(huì)一直等待
這樣就導(dǎo)致大量的線程hung在這里了(基本是只要方法被調(diào)一次,就會(huì)產(chǎn)生一個(gè)hung住的線程),所以有大量空線程一直占用,造成嚴(yán)重的線程泄漏
總結(jié)
在自定義線程池且未交給spring容器管理時(shí),使用完畢的線程池一定要執(zhí)行shutDown()手動(dòng)關(guān)閉線程池,這是編程上的疏忽。
找到原因后感覺問題很簡(jiǎn)單,但是查找過程中還是碰壁不少,找過幾次都沒有找到最終原因。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
深入解析面向?qū)ο缶幊淘贘ava中的應(yīng)用小結(jié)
本文詳細(xì)介紹了面向?qū)ο缶幊痰幕靖拍?包括類和對(duì)象、封裝、繼承和多態(tài),通過具體的Java代碼示例,展示了如何在Java中應(yīng)用這些面向?qū)ο缶幊痰暮诵乃枷?感興趣的朋友跟隨小編一起看看吧2025-01-01java中hashCode方法與equals方法的用法總結(jié)
總的來說,Java中的集合(Collection)有兩類,一類是List,再有一類是Set。前者集合內(nèi)的元素是有序的,元素可以重復(fù);后者元素?zé)o序,但元素不可重復(fù)2013-10-10java實(shí)現(xiàn)系統(tǒng)捕獲異常發(fā)送郵件案例
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)系統(tǒng)捕獲異常發(fā)送郵件案例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11使用maven命令安裝jar包到本地倉(cāng)庫的方法步驟
這篇文章主要介紹了使用maven命令安裝jar包到本地倉(cāng)庫的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06