分享一次cpu98%的問題排查

1.第一步 執行top,很明顯pid是1的進程的cpu佔用特別高

 

 

2.第二步 執行top -Hp 1,查看到進程1下面的pid是8,9,10,11這四個線程的cpu佔用比較異常

對應java程序裏的tid是0x8 0x9 0xa 0xb。

3.第三步執行jstack 1 > 20191107.log 獲取到日誌文件,查到剛好是垃圾回收的幾個線程

 

4.第四步再執行jstat -gcutil 1 2000

發現FGC很頻繁,而且有沒次fgc的效率不高,就算回收了還是暫用97、98%,說明有大量的老年代對象沒有被回收

5.第五步,是什麼原因導致老年代對象沒有被回收呢,首先我們先執行java -XX:+PrintCommandLineFlags -version

查看jvm的堆參數配置以及垃圾回收器

最大堆內存大小是2G 左右,垃圾回收是ParallelGC 並行垃圾回收器

newRatio 等於2,老年代,佔比2/3,4/3g * 98% = 1.306g的老年代堆內存一直不能被回收。

6.第六步,執行jmap -dump:format=b,file=20191029.dump 1,生成dump文件,使用visualVm工具打開dump文件,

分析發現有很多boundSql佔用了大量的內存,並且不能被釋放,這條sql是updateBatchById,查詢數據庫,

這條sql一直被佔用,並且不會被釋放。查閱代碼,發現有一條批量更新語句,使用case id  when  then 的語法,這條批量更新語句更新大概2w行數據,導致數據庫SQL語句執行緩慢,e其實是固定的,沒有必要這樣寫sql。後修改SQL 爲updat a set  a.c = d where e = xxx,重新部署,運行一段時間,服務器的cpu一直正常。

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