如何排查Java應用內存泄漏問題


什么是內存泄漏

內存泄漏是指java應用的堆內存使用率持續升高,直至內存溢出。
內存泄漏的的原因可能有多種

  • 分配給應用程序的內存本身過小。而應用的業務代碼,確實需要生成大量的對象
  • 代碼bug,某些需要被回收的對象,由於代碼bug,卻持續的被引用,導致java虛擬機無法回收這些對象。從而撐爆內存

無論哪種內存泄露,我們的解決方法都是要定位到具體是什么對象,占用了大量內存,從而方便我們基於此進行代碼分析,debug,找出代碼問題。
而能夠幫助我們實現這一目的的方式就是獲取java應用的內存 dump

如何獲取內存dump

使用命令獲取jcmd

首先需要獲取java 進程id,獲取到java進程后
使用命令

jcmd <pid> GC.heap_dump <file-path>

如果執行報錯

com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded

一般是由於執行jcmd的用戶同java應用本身不是同一個用戶。解決辦法是切換到應用對應的用戶下再執行上述命令

sudo -u [userid] /jcmd <pid> GC.heap_dump <file-path>

如果應用在本地

如果應用是在本地,除了用上述方法外,還可以用JVisualVM 、JConsole

程序異常退出時自動dump

但更為重要的,為了准確還原應用故障的現場,最好通過指定java 執行參數,在程序出錯時,自動dump

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>

如何分析內存dump

獲取到dump文件后,需要使用eclipse.org 出品的 Memory Analyzer 工具。使用其中的Dominator Tree,查看各對象的內存占用情況
file

找出占用內存最多的對象及其類信息
file

參考資料

https://www.baeldung.com/java-heap-dump-capture
https://www.cnblogs.com/alcc/p/9905705.html
https://www.eclipse.org/mat/

歡迎關注我的個人公眾號"西北偏北UP",記錄代碼人生,行業思考,科技評論


免責聲明!

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



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