常见性能问题-内存泄漏

内存为什么会泄漏?内存泄漏的现象是什么?出现内存泄漏怎么定位?
备注:想要更好的理解内存泄漏,需要关注前面的内存模型和java虚拟机分代收集过程
 
(1)、内存溢出和内存泄露
溢出:是个结果,对内存没有空间了,就会溢出;
泄漏:是个过程,比如代码中对象被引用后一直没有释放,最终导致内存溢出;
 
(2)、内存溢出的现象
 
通过top命令监控,cpu几乎打满,占用率接近百分百,因为出发young gc的时候是消耗CPU的,尤其是full gc的时候消耗更多,所以CPU被占满,
当我们停止外界压力,或者重新访问,都不能使cpu降下来,只有重新启动Tomcat,重新分配内存;
 
 
(2)、内存泄露怎么定位
第一步:查看tomcat进程号,命令 jmap -heap 进程号,查看堆内存的使用情况
a、红色箭头指的是jvm的基本属性信息,不用关注
b 、总体显示如下
c、下面红色箭头,指的是伊甸园区的总共大小,使用的大小,剩余的大小,和利用率;
下面的红色箭头含义已标注;
d、如果伊甸园区已用的内存+一个存活区已用内存的大小>老年代剩余的内存大小,将会内存溢出;
 
 
第二步:jmap -histo 进程号:定位内存溢出最快的方法
文件太长,重定向显示如下:
num:序号
nistances:实例
bytes:字节大小
class name:类名
分析:
内存溢出,先分析大对象,也就是先分析占用内存多的对象,排在前几位的可能是带公司名的jar包,那就是jar包的问题;如果排在前几位的是char、string 等类型,无法分析,那就要用工具分析,用mat
mat是eclipse中的一个插件,后来单独作为工具使用;
(mat的使用后续单独写一篇博客)
 
第三步:用mat分析,需要用命令 jmap -dump下载一份heap.bin文件,但是每dump一次就会触发一次gc,因此,线上系统禁止使用dump;(命令的用法多参考帮助文档)
 
备注:如果不用mat,dump成功之后,可以通过命令 jhat heap.bin ,起一个java服务
 
根据端口访问:页面如下,在页面统计分析,不提倡,了解即可。
 
总结:
用 jmap -histo 快速定位,无法分析出问题所在的时候,用jmap -dump,dump出一份heap.bin文件,
再用jhat heap.bin 命令(相当于启动一个java服务),然后在页面根据端口进行分析(这种方法太low),
用mat 分析heap.bin 文件。
 
内存溢出是不是给内存分配更大的内存就能解决?
加内存能够解决一些性能问题,但是不是内存越大越好,内存越大,full gc的间隔越长,但是每次full gc的时间也越长,如果gc的时间过长,会给用户造成系统宕机的感觉,所以内存够用即可。

posted @ 2021-07-23 01:00  大黄与小白  阅读(142)  评论(0)    收藏  举报