內存泄漏導致頻繁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 28679jinfo -flag +HeapDumpAfterFullGC 28679,在Full GC之前和Full GC之后dump堆內存快照(注意:dump完成之后,一定要關閉這兩個參數,不然頻繁Full GC 導致頻繁dump,會占用大量磁盤空間);使用命令jinfo -flag -HeapDumpBeforeFullGC 28679jinfo -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,就是它導致了內存泄漏。剩下的就需要業務同學排查代碼了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM