無法執行任何java命令,報錯OutOfMemoryError: Cannot create GC thread. Out of system resources

生產程序功能不執行了,遠程定位時發現無法使用jps,jstack甚至java -version命令,所有的java命令都無法執行,報錯爲無法創建線程.
$jps -ml
Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.

查看程序日誌發現有unable to create new native thread類似無法創建線程的報錯
內存及CPU空閒較多,資源充足排除內存不足的影響,只能懷疑是哪裏限制了最大線程數.
查看線程數限制:ulimit -u
ulimit -a

cat /etc/security/limit.conf

cat /etc/sysctl.conf 
查看各系統用戶的進程數的命令如下所示,執行後可得類似如下結果。命令中的L是將(Java線程)輕量級進程也計算在內
# ps h -Led -o user | sort | uniq -c | sort -n
用戶進程數(LWP)的分佈情況。命令如下,查詢結果類似如下。
# ps -o nlwp,pid,lwp,args -u username | sort -n

線程數3萬多,但還沒有達到最大限制65536,繼續查看其他地方有沒有限制。

# /proc/sys/kernel/threads-max物理內存決定的系統進程數上限
# /proc/sys/kernel/pid_max這個值表示進程ID的上限
# /proc/sys/vm/max_map_count限制一個進程可以擁有的VMA(虛擬內存區域)的數量
cat /proc/sys/kernel/threads-max
cat /proc/sys/vm/max_map_count
cat /etc/security/limits.d/90-nproc.conf 
cat /proc/sys/kernel/pid_max
pid_max進程ID的上限默認爲32768 ,現在的線程數很接近了,應該是這裏限制了,原因找到了,但是爲什麼會創建這麼多線程呢?如果線程一直增加,即使加大進程ID上限也早晚會達到的,必須找到根本原因。
查看重啓後的線程數
ps h -Led -o user | sort | uniq -c | sort -n
發現每次程序運行一個Job之後,線程數就會增加一個,而且對比一段時間內的線程發現之前的線程沒有釋放,且增加的線程名都是pool-開頭,說明是線程池內創建的線程。
jstack -l pid| grep pool- |wc -l
懷疑某個線程池的線程無法回收,排查代碼發現某個同事寫的bug(低級問題,必須甩鍋啊), 創建線程池未關閉,線程池不關閉,其中的線程不會釋放,且每次都錯誤的新建線程池而非提交任務到同一個線程池。錯誤不復雜,修改很簡單,但是現象很詭異,定位過程很曲折。
 
參考:

https://access.redhat.com/solutions/22105

https://blog.csdn.net/beatle_1983/article/details/50435751

https://www.jianshu.com/p/0bf0b3f889d6

https://www.cnblogs.com/autopenguin/p/6184886.html

http://blog.chinaunix.net/uid-20662820-id-5690021.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章