jprofiler分析dump文件_内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)...
點(diǎn)擊上方 "Java指南者"關(guān)注,?星標(biāo)或置頂一起成長
免費(fèi)送 1024GB 精品學(xué)習(xí)資源?
來源:https://zhanghan.blog.csdn.net/article/details/109255980
前言
最近剛上線了一款社交項(xiàng)目,運(yùn)行十多天后(運(yùn)營持續(xù)每天推量),發(fā)現(xiàn)問題:
- 系統(tǒng) OOM(資源不能被釋放)導(dǎo)致服務(wù)器頻繁且長時(shí)間 FGC 導(dǎo)致服務(wù)器 CPU 持續(xù)飚高
- 日志中內(nèi)存溢出:java.lang.OutOfMemoryError: Java heap space
- 程序十分卡頓,嚴(yán)重影響用戶使用
從以下方面,為大家分享此次問題解決流程
- 問題出現(xiàn)現(xiàn)象
- 臨時(shí)解決方案
- 復(fù)現(xiàn)問題
- 定位問題發(fā)生原因
- 優(yōu)化代碼
- 優(yōu)化后進(jìn)行壓測,上線
- 復(fù)盤
學(xué)完本博文,你的收獲
- 排查內(nèi)存溢出的思路
- 排查內(nèi)存溢出過程中用到的命令及工具(Linux 命令,Eclipse Memory Anaylzer[MAT])
- 定位系統(tǒng)內(nèi)存溢出的代碼,并進(jìn)行優(yōu)化
- 此次內(nèi)存溢出問題復(fù)盤
- 解決方案流程圖
問題&臨時(shí)解決方案&定位問題&最終解決方案
問題:
業(yè)務(wù)反饋程序用的十分卡,同時(shí)測試自己測的也十分卡
從 ELK 收集的請求日志發(fā)現(xiàn)確實(shí)存在問題,線上是兩臺(tái)部署:兩臺(tái)機(jī)器上都是,一次請求耗時(shí)由原來的幾毫秒變?yōu)?10 幾秒
CPU 跑的過高,當(dāng)時(shí)是 4 核,CPU 持續(xù)飆到 350%+;
當(dāng)時(shí)一臺(tái)服務(wù)器 CPU 截圖:
臨時(shí)解決方案
- 當(dāng)時(shí)為了減少對業(yè)務(wù)影響,直接將生產(chǎn)兩臺(tái)服務(wù)器上的項(xiàng)目進(jìn)行重啟
- 項(xiàng)目啟動(dòng)參數(shù)中沒有加內(nèi)存溢出日志輸出(后續(xù)博客為大家介紹 JVM 調(diào)優(yōu)時(shí)講解啟動(dòng)命令中加內(nèi)存溢出日志輸出),重啟后出問題時(shí)項(xiàng)目的 JVM 信息丟失了
復(fù)現(xiàn)問題方式:在開發(fā)環(huán)境對程序進(jìn)行持續(xù)壓測;壓測相關(guān)服務(wù)器配置:
服務(wù)器配置:8 核,16G
項(xiàng)目啟動(dòng)內(nèi)存:136M
Jmeter 持續(xù)(循環(huán))壓發(fā)消息接口 10 分鐘
定位問題
top 命令查看最耗 CPU 的進(jìn)程(進(jìn)程:17038;CPU 持續(xù)飆到 595%+)
#?輸入top命令后鍵入P(大寫P),進(jìn)程按照CPU從高到底排序top
- 查看該進(jìn)程中最耗 CPU 的線程(發(fā)現(xiàn)有一些線程占用 CPU 較高)
top?-Hp?17038
- 將線程號(hào)轉(zhuǎn)為 16 進(jìn)制,同時(shí)查看這些線程當(dāng)前正在干什么(在此以 17045 線程為例
printf?'%x\n'?17045
#?17038為進(jìn)程號(hào),0x4295為最耗CPU線程的十六進(jìn)制
jstack?17038?|?grep?'0x4295'?-C10?--color
可以看到最耗 CPU 的線程都是在進(jìn)行 GC
用 Jmap 命令查看當(dāng)前堆的使用情況(發(fā)現(xiàn)老年代現(xiàn)在已占用 99.8%+)
jmap?-heap?17038
- 查看 gc 頻率的命令(其中 O 代表老年代占用率,FGC 是 FullGC 次數(shù),FGCT 是 fullGC 時(shí)間;可以看出在頻繁 FullGC 但是老年代有資源一直釋放不掉)
jstat?-gcutil?17038?5000
- 通過分析出問題時(shí)線上日志發(fā)現(xiàn)內(nèi)存溢出;至此定位到問題根源是內(nèi)存溢出導(dǎo)致(有未釋放資源堆積,導(dǎo)致老年代被占滿,然后頻繁的 FullGC 但是資源一直釋放不了)
分析問題產(chǎn)生原因
由于線上當(dāng)時(shí)直接重啟,未能保留當(dāng)時(shí)的 JVM 內(nèi)存文件;在開發(fā)環(huán)境進(jìn)行循環(huán)壓測,復(fù)現(xiàn)線上問題,然后導(dǎo)出 dump 文件進(jìn)行分析找到原因
生成 dump 文件命令
jmap?-dump:format=b,file=fileName.dump?pid
1
2
將 dump 文件導(dǎo)出到本地,用 Eclipse Memary Analysis(MAT 官網(wǎng)下載地址) 進(jìn)行分析
MAT 導(dǎo)入 dump 文件
- 按對象排序視圖進(jìn)行查看(總覽中看到對象總個(gè)數(shù):14.1 百萬個(gè))
- 發(fā)現(xiàn)有兩個(gè)類(ClassClassPath,ClassClassPathList)占用比較大,這兩個(gè)類約占對象總數(shù)的 83%(計(jì)算方式:5873361*2/14100000=83%)
分析代碼
- 去代碼中全局搜這兩個(gè)類,發(fā)現(xiàn)只有在打日志的時(shí)候用到 ClassClassPath 類
分析 ClassClassPath 相關(guān)代碼:
用到 ClassClassPath 對象是一個(gè)靜態(tài)的 ClassPool;
問題原因:classPath 一直被靜態(tài)的全局 pool 所持有,導(dǎo)致 GC 一直釋放不掉;
- 當(dāng)然順著代碼,順藤摸瓜也找到了 ClassPathList
優(yōu)化代碼:每次用完 ClassClassPath 后將其釋放
每次對象使用完后從靜態(tài) pool 中移除
注意:classPath=null 這種方式是不能釋放掉的
優(yōu)化后再次進(jìn)行驗(yàn)證
- 開發(fā)環(huán)境循環(huán)壓測,用 MAT 分析 dump 文件,發(fā)現(xiàn)內(nèi)存中已不再堆積 ClassClassPath 類;優(yōu)化前后接口吞吐量也提升 8.2%
- 進(jìn)行線上發(fā)布,觀察一周后,對內(nèi)存分析發(fā)現(xiàn)正常
復(fù)盤:
項(xiàng)目比對:
為快速開發(fā),社交的代碼從原來金融項(xiàng)目基礎(chǔ)上改造而來;
原來金融項(xiàng)目沒有內(nèi)存溢出,而社交項(xiàng)目為什么內(nèi)存溢出?
通過 ELK 統(tǒng)計(jì)一段時(shí)間的訪問量結(jié)果:
- 社交目前日訪問后臺(tái)量 65w+
- 金融項(xiàng)目只有 4.5W+
社交和金融項(xiàng)目業(yè)務(wù)類型不一樣,所呈現(xiàn)出的特點(diǎn)也不同
去生產(chǎn)的金融項(xiàng)目中 dump 內(nèi)存文件,用 MAT 工具分析,發(fā)現(xiàn)也存在 ClassClassPath 類堆積釋放不掉,只不過由于訪問量少,堆積量未占滿老年代而已;果斷在金融項(xiàng)目迭代時(shí)將其優(yōu)化;
程序預(yù)警:為減少業(yè)務(wù)影響,增加接口耗時(shí)的預(yù)警(后續(xù)博文為大家共享);實(shí)現(xiàn)方式:
在每次程序處理完進(jìn)行預(yù)警(比如本次請求>閾值);缺點(diǎn):消耗性能影響正常業(yè)務(wù)
在 ELK 清洗時(shí)用相關(guān)插件進(jìn)行預(yù)警;優(yōu)點(diǎn):和業(yè)務(wù)解耦,對業(yè)務(wù)無影響
服務(wù)器預(yù)警:運(yùn)維增加 CPU 內(nèi)存,日志內(nèi)存溢出監(jiān)控
總結(jié)
解決內(nèi)存溢出過程總結(jié):
不同的項(xiàng)目導(dǎo)致內(nèi)存溢出原因是不同的;
重要的是排查思路
經(jīng)過不斷的耐心的去觀察,測試,分析才能定位到問題并最終解決問題
在這次分析內(nèi)存溢出過程中,我們也針對我們項(xiàng)目的 JVM 啟動(dòng)參數(shù)進(jìn)行了調(diào)優(yōu),在接下來的博文中為大家分享 JVM 調(diào)優(yōu)
熱門內(nèi)容:
兩年經(jīng)驗(yàn)斬獲螞蟻/頭條/PingCAP Offer,牛逼了
字節(jié)跳動(dòng)熱騰騰的面經(jīng)分享深入理解 Java 內(nèi)存模型關(guān)注我
關(guān)注我,Java 學(xué)習(xí)不迷路!
與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的jprofiler分析dump文件_内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python网络爬虫的论文模板_Pyth
- 下一篇: python解包操作_Python编程使