java内存泄漏问题检测与定位

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a7895906/article/details/74674561

内存泄漏是程序中不可避免的问题,当一个程序的并发量上去后,内存泄漏最后会导致内存溢出。


本篇主要是模拟java程序中内存泄漏的定位,找到程序中内存泄漏问题的根源


首先在myeclipse上安装一个插件,Eclipse Memory Analyzer,安装方式

打开Help -> install from site 





下载地址 :http://download.eclipse.org/mat/1.3/update-site/



点击OK,之后next下载即可,这里就eclipse memory Analyzer tool就安装成功


首先,我在后台程序的一个函数中加入内存泄漏代码。如图所示:



test是一个静态全局变量,当服务启动后,他的生命周期与服务是一样长的。


运行tomcat


cmd运行jconsole,找到对应的tomcat进程并连接



查看堆内存使用情况(这里主要看老生代)




可以看到从15.29之后老生代内存暴涨,这说明程序里有内存堆积。。。


在cmd里用jmap生成堆存储快照 


命令最后一个数字是tomcat的运行进程号,此时在对应的路径下,你会发现生成了一个堆存储文件myhead


回到eclipse,File - openFile 打开这个文件

生成如下图所示的结果




点击红圈处,结果如下图



由上图我们可以发现第三行 test这个对象的shallow Heap 是24, Retained Heap 是69676584,几乎占满了堆内存(相差好大),经过百度得知, shallow heap表示对象本身的大小不包括它的引用,而Retained Heap表示对象 + 它所引用的所有对象的大小的总和。 这样便明白了,test本身是一个List引用,只占据24,但是程序运行之后,我们疯狂地往test里add大块元素,这些元素或许在我们程序中是无用的,但是却被test引用无法回收,最终导致堆内存爆满,产生内存溢出。。。


因为,当我们能定位到是test导致内存泄漏,我们就能够定位到相应的代码进行处理。


总结: 可以先通过jconsole来检测程序堆内存情况(主要是老生代),当老生代内存异常时,使用jmap命令生成内存快照,用eclipse memory Analyzer tools工具打开该内存                快照进行定位。。。


展开阅读全文

没有更多推荐了,返回首页