https://blog.csdn.net/m0_37542440/article/details/123679011
1. 問題情況
在服務(wù)器上執(zhí)行某個任務(wù)時,系統(tǒng)突然運行緩慢,top 發(fā)現(xiàn)cpu飆升,一度接近100%,最終導(dǎo)致服務(wù)假死。
2. 問題排查
1. 執(zhí)行 “top” 命令:查看所有進程占系統(tǒng)cpu的排序,極大可能排第一的就是自己的java進程,pid就是進程號。
2. 執(zhí)行 “top -Hp 進程號” 命令:查看java進程下的所有線程占cpu情況。
3. 執(zhí)行 “printf "%x\n" 10” 命令:后續(xù)查看線程堆棧信息展示的都是十六進制,為了找到咱們的線程堆棧信息,需要把線程號轉(zhuǎn)為16進制。例如,printf "%x\n 10-》打?。篴,那么在jstack中線程號就是0xa。
4. 執(zhí)行 “jstack 進程號 | grep 線程id” 命令:查找某進程下-》線程id(jstack堆棧信息中的nid)=0xa的線程狀態(tài)。如果“"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable”,第一個雙引號圈起來的就是線程名,如果是“VM Thread”這就是虛擬機GC回收線程了。
5. 執(zhí)行 “jstat -gcutil 進程號 統(tǒng)計間隔毫秒 統(tǒng)計次數(shù)(缺省代表一致統(tǒng)一)”,查看某進程GC持續(xù)變化情況,如果發(fā)現(xiàn)返回中FGC很大且一直增大,確認Full GC 也可以使用“jmap -heap 進程ID”,查看一下進程堆內(nèi)是不是要溢出了,特別是老年代內(nèi)從使用情況一般是到達閾值(具體看垃圾回收器和啟動配置的閾值)就回晉城Full GC。
6. 執(zhí)行 “jmap -dump:format=b,file=filename 進程ID”,導(dǎo)致某進程下內(nèi)存heap輸出到文件中,可以通過eclipse的mat工具查看內(nèi)存中有哪些對象比較多。
6-1. jmap?
jmap -dump:live,format=b,file=live_web_dump.hprof 22260
借鑒:JVM調(diào)優(yōu)命令-jmap - 鈺火 - 博客園
3. 原因分析
1. 內(nèi)存消耗過啊,導(dǎo)致Full GC次數(shù)過多
執(zhí)行步驟1-5:
多個線程的CPU都超過了100%,通過jstack命令可以看到這些線程主要是垃圾回收線程-》上一節(jié)步驟2
通過jstat命令監(jiān)控GC情況,可以看到Full GC次數(shù)非常多,并且次數(shù)在不斷增加。--》上一節(jié)步驟5
確定是Full GC,接下來找到具體原因:
生成大量的對象,導(dǎo)致內(nèi)存溢出-》執(zhí)行步驟6,查看具體內(nèi)存對象占用情況。
內(nèi)存占用不高,但是Full GC次數(shù)還是比較多,此時可能是代碼中手動調(diào)用 System.gc()導(dǎo)致GC次數(shù)過多,這可以通過添加 -XX:+DisableExplicitGC來禁用JVM對顯示GC的響應(yīng)。
2.代碼中有大量消耗CPU的操作,導(dǎo)致CPU過高,系統(tǒng)運行緩慢;
執(zhí)行步驟1-4:在步驟4jstack,可直接定位到代碼行。例如某些復(fù)雜算法,甚至算法BUG,無限循環(huán)遞歸等等。
3.由于鎖使用不當,導(dǎo)致死鎖。
執(zhí)行步驟1-4: 如果有死鎖,會直接提示。關(guān)鍵字:deadlock.步驟四,會打印出業(yè)務(wù)死鎖的位置。
造成死鎖的原因:最典型的就是2個線程互相等待對方持有的鎖。
4.隨機出現(xiàn)大量線程訪問接口緩慢。
代碼某個位置有阻塞性的操作,導(dǎo)致該功能調(diào)用整體比較耗時,但出現(xiàn)是比較隨機的;平時消耗的CPU不多,而且占用的內(nèi)存也不高。
思路:
首先找到該接口,通過壓測工具不斷加大訪問力度,大量線程將阻塞于該阻塞點。
5.某個線程由于某種原因而進入WAITING狀態(tài),此時該功能整體不可用,但是無法復(fù)現(xiàn);文章來源:http://www.zghlxwxcb.cn/news/detail-612152.html
執(zhí)行步驟1-4:jstack多查詢幾次,每次間隔30秒,對比一直停留在parking 導(dǎo)致的WAITING狀態(tài)的線程。例如CountDownLatch倒計時器,使得相關(guān)線程等待->AQS(AbstractQueuedSynchronizer AQS框架源碼剖析)->LockSupport.park()。文章來源地址http://www.zghlxwxcb.cn/news/detail-612152.html
到了這里,關(guān)于JVM-Cpu飆升排查及解決的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!