一、内存泄漏与内存溢出
1、内存溢出:简单来理解就是,你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,出现溢出。

2、内存泄漏:你用new申请了一块内存,后来很长时间都不再使用了(按理应该释放),但是因为一直被某个或某些实例所持有导致 GC 不能回收,也就是该被释放的对象没有释放。
2.1出现内存泄漏与内存溢出的原因?

为什么出现内存溢出(out of memory )?

1)JVM内存过小。
2)程序不严密,产生了过多的垃圾。

为什么会发生内存泄漏(leak of memory)?
举个例子:
如下图:对象A是指对象B。A的生命周期(t1 - t4)比B的(t2 - t3)长得多,当应用中不再使用B时,A仍然有一个B的引用,这样垃圾收集器就不能从内存中删除B。这就可能会导致内存不足的问题,因为如果A同时为更多的对象做同样的事情,那么会有很多像B这样的对象没有收集并占用内存空间。

B也可能拥有一堆其他对象的引用,B引用的对象也不会被收集。所有这些未使用的对象将消耗宝贵的内存空间。
关于内存泄漏与内存溢出
2.2内存泄漏与内存溢出的联系

内存泄露会最终会导致内存溢出。
相同点:都会导致应用程序运行出现问题,性能下降或挂起。
不同点:1) 内存泄露是导致内存溢出的原因之一,内存泄露积累起来将导致内存溢出。
2) 内存泄露可以通过完善代码来避免,内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

二、如何排查内存泄漏
2.1 确定频繁Full GC现象
jps命令格式为:
jps [ options ] [ hostid ]
使用命令如下:
使用jps:jps -l

使用ps:ps aux | grep tomat 找到你需要监控的ID(假设为10765),再利用“虚拟机统计信息监视工具:jstat”监视虚拟机各种运行状态信息。

jstat命令格式为:
jstat [ option vmid [interval[s|ms] [count]] ]
使用命令如下:
jstat -gc 10765 1000
意思是每1000毫秒查询一次,一直查。

根据jstat分析:
关于内存泄漏与内存溢出
主要查看:
EC:Eden区容量,EU:Eden区已使用量,OC:Old区容量,OU:Old区已使用量;
YGC:YongGC次数,YGCT:YongGC耗时,FGC:FullGC次数,FGCT:FullGC耗时

2.2 找出导致频繁Full GC的原因
1)把堆dump下来再用MAT等工具进行分析;
2)jmap”生成堆转储快照(一般称为headdump或dump文件);
jmap命令格式:
jmap [ option ] vmid
使用命令如下:
jmap -histo:live 10765
查看存活的对象情况,如下图所示:
关于内存泄漏与内存溢出
数据不正常,十有八九就是泄露的。

2.3定位到代码

相关文章: