日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jprofiler分析dump文件_内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)...

發布時間:2025/3/15 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jprofiler分析dump文件_内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊上方 "Java指南者"關注,?星標或置頂一起成長

免費送 1024GB 精品學習資源?

來源:https://zhanghan.blog.csdn.net/article/details/109255980

前言

最近剛上線了一款社交項目,運行十多天后(運營持續每天推量),發現問題:

  • 系統 OOM(資源不能被釋放)導致服務器頻繁且長時間 FGC 導致服務器 CPU 持續飚高
  • 日志中內存溢出:java.lang.OutOfMemoryError: Java heap space
  • 程序十分卡頓,嚴重影響用戶使用

從以下方面,為大家分享此次問題解決流程

  • 問題出現現象
  • 臨時解決方案
  • 復現問題
  • 定位問題發生原因
  • 優化代碼
  • 優化后進行壓測,上線
  • 復盤

學完本博文,你的收獲

  • 排查內存溢出的思路
  • 排查內存溢出過程中用到的命令及工具(Linux 命令,Eclipse Memory Anaylzer[MAT])
  • 定位系統內存溢出的代碼,并進行優化
  • 此次內存溢出問題復盤
  • 解決方案流程圖

問題&臨時解決方案&定位問題&最終解決方案

問題:

  • 業務反饋程序用的十分卡,同時測試自己測的也十分卡

  • 從 ELK 收集的請求日志發現確實存在問題,線上是兩臺部署:兩臺機器上都是,一次請求耗時由原來的幾毫秒變為 10 幾秒

  • CPU 跑的過高,當時是 4 核,CPU 持續飆到 350%+;

  • 當時一臺服務器 CPU 截圖:

臨時解決方案

  • 當時為了減少對業務影響,直接將生產兩臺服務器上的項目進行重啟
  • 項目啟動參數中沒有加內存溢出日志輸出(后續博客為大家介紹 JVM 調優時講解啟動命令中加內存溢出日志輸出),重啟后出問題時項目的 JVM 信息丟失了

復現問題方式:在開發環境對程序進行持續壓測;壓測相關服務器配置:

  • 服務器配置:8 核,16G

  • 項目啟動內存:136M

  • Jmeter 持續(循環)壓發消息接口 10 分鐘

定位問題

top 命令查看最耗 CPU 的進程(進程:17038;CPU 持續飆到 595%+)

#?輸入top命令后鍵入P(大寫P),進程按照CPU從高到底排序
top

  • 查看該進程中最耗 CPU 的線程(發現有一些線程占用 CPU 較高)
17038為進程號,鍵入P(大寫P),該進程中的線程按照CPU從高到底排序
top?-Hp?17038
  • 將線程號轉為 16 進制,同時查看這些線程當前正在干什么(在此以 17045 線程為例
#?將線程號轉為16進制;其中17045為線程號
printf?'%x\n'?17045
#?17038為進程號,0x4295為最耗CPU線程的十六進制
jstack?17038?|?grep?'0x4295'?-C10?--color
  • 可以看到最耗 CPU 的線程都是在進行 GC

  • 用 Jmap 命令查看當前堆的使用情況(發現老年代現在已占用 99.8%+)

#?其中17038為進程號
jmap?-heap?17038
  • 查看 gc 頻率的命令(其中 O 代表老年代占用率,FGC 是 FullGC 次數,FGCT 是 fullGC 時間;可以看出在頻繁 FullGC 但是老年代有資源一直釋放不掉)
#?其中17038為進程號,5000是指每5秒(5000毫秒)輸出一次
jstat?-gcutil?17038?5000
  • 通過分析出問題時線上日志發現內存溢出;至此定位到問題根源是內存溢出導致(有未釋放資源堆積,導致老年代被占滿,然后頻繁的 FullGC 但是資源一直釋放不了)
grep?-m?10?'OutOfMemoryError'?*.log

分析問題產生原因

  • 由于線上當時直接重啟,未能保留當時的 JVM 內存文件;在開發環境進行循環壓測,復現線上問題,然后導出 dump 文件進行分析找到原因

  • 生成 dump 文件命令

#?其中fileName是導出后dump名稱,pid為進程號
jmap?-dump:format=b,file=fileName.dump?pid
1
2
  • 將 dump 文件導出到本地,用 Eclipse Memary Analysis(MAT 官網下載地址) 進行分析

  • MAT 導入 dump 文件

  • 按對象排序視圖進行查看(總覽中看到對象總個數:14.1 百萬個)
  • 發現有兩個類(ClassClassPath,ClassClassPathList)占用比較大,這兩個類約占對象總數的 83%(計算方式:5873361*2/14100000=83%)

分析代碼

  • 去代碼中全局搜這兩個類,發現只有在打日志的時候用到 ClassClassPath 類

分析 ClassClassPath 相關代碼:

  • 用到 ClassClassPath 對象是一個靜態的 ClassPool;

  • 問題原因:classPath 一直被靜態的全局 pool 所持有,導致 GC 一直釋放不掉;

  • 當然順著代碼,順藤摸瓜也找到了 ClassPathList
  • 優化代碼:每次用完 ClassClassPath 后將其釋放

  • 每次對象使用完后從靜態 pool 中移除

  • 注意:classPath=null 這種方式是不能釋放掉的

優化后再次進行驗證

  • 開發環境循環壓測,用 MAT 分析 dump 文件,發現內存中已不再堆積 ClassClassPath 類;優化前后接口吞吐量也提升 8.2%
  • 進行線上發布,觀察一周后,對內存分析發現正常

復盤:

項目比對:

  • 為快速開發,社交的代碼從原來金融項目基礎上改造而來;

  • 原來金融項目沒有內存溢出,而社交項目為什么內存溢出?

  • 通過 ELK 統計一段時間的訪問量結果:

    • 社交目前日訪問后臺量 65w+
    • 金融項目只有 4.5W+
  • 社交和金融項目業務類型不一樣,所呈現出的特點也不同

  • 去生產的金融項目中 dump 內存文件,用 MAT 工具分析,發現也存在 ClassClassPath 類堆積釋放不掉,只不過由于訪問量少,堆積量未占滿老年代而已;果斷在金融項目迭代時將其優化;

  • 程序預警:為減少業務影響,增加接口耗時的預警(后續博文為大家共享);實現方式:

  • 在每次程序處理完進行預警(比如本次請求>閾值);缺點:消耗性能影響正常業務

  • 在 ELK 清洗時用相關插件進行預警;優點:和業務解耦,對業務無影響

  • 服務器預警:運維增加 CPU 內存,日志內存溢出監控

總結

解決內存溢出過程總結:

  • 不同的項目導致內存溢出原因是不同的;

  • 重要的是排查思路

  • 經過不斷的耐心的去觀察,測試,分析才能定位到問題并最終解決問題

在這次分析內存溢出過程中,我們也針對我們項目的 JVM 啟動參數進行了調優,在接下來的博文中為大家分享 JVM 調優


熱門內容:

兩年經驗斬獲螞蟻/頭條/PingCAP Offer,牛逼了

字節跳動熱騰騰的面經分享深入理解 Java 內存模型

關注我

關注我,Java 學習不迷路!

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的jprofiler分析dump文件_内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。