內存泄漏導致頻繁 Full GC【轉】

1、問題發現

       Prometheus 報警 user-center 服務的 Old GC 過多,需要排查

2、問題分析

      user-center 服務生產環境部署 4 個結點,整個堆的大小設置爲 2g,新生代的大小設置爲 1g。這次的報警,4 個結點都有報,查看其中一個結點發現該結點,從 10 點 30 分左右到 11 點 20 分左右,不到一個小時的時間裏,竟然產生了 5 次 Full GC,這個是極其不正常的。 

3、使用 GCViewer 分析 GC 日誌

       可以看出,整個老年代 1g 的內存,幾乎已經全部被佔用了,而且在 Full GC 之後,並沒有回收多少內存,很顯然,內存泄漏了。內存泄漏導致老年代內存空間不足,新生代的對象到了一定的年齡,需要提升,提升時發現老年代內存不夠,就進行 Full GC,但每次 Full GC 之後,並沒用回收多少內存,雖然並沒有導致 OOM,但是很快下次提升就又需要 Full GC 了。

4、dump 堆快照文件

       使用命令 jinfo -flag +HeapDumpBeforeFullGC 28679  jinfo -flag +HeapDumpAfterFullGC 28679,在 Full GC 之前和 Full GC 之後 dump 堆內存快照(注意:dump 完成之後,一定要關閉這兩個參數,不然頻繁 Full GC 導致頻繁 dump,會佔用大量磁盤空間);使用命令 jinfo -flag -HeapDumpBeforeFullGC 28679  jinfo -flag -HeapDumpAfterFullGC 28679 關閉兩個參數。其實也可以不用非要加上這兩個參數然後等待 Full GC 的出現,由於是內存泄漏,老年代內存不能回收,那麼直接使用命令 jmap -dump:format=b,file=before.hprof 28679  jmap -dump:live,format=b,file=after.hprof 28679 來 dump 堆快照文件也是可以的,加上 live 表示只保存存活對象。

5、使用 Eclipse MAT 分析對快照

      很顯然可以看到堆內存被對象 DoctorInvitePictureManagerImpl 佔用了 811.8M,就是它導致了內存泄漏。剩下的就需要業務同學排查代碼了。

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