为什么会发生内存泄露?

2117 篇文章 51 订阅
845 篇文章 1 订阅
文章讨论了内存泄露和资源泄露的概念,指出它们通常发生在对象引用丢失或未正确关闭资源的场景。内存泄露常见于static集合,而排查可能通过jmap等工具进行。避免内存泄露的方法包括减少static集合使用,利用弱引用,并强调正确管理资源。文章还提到了内存使用过高不一定是泄露,可能由错误的内存使用引起,提供了排查和解决内存问题的步骤。
摘要由CSDN通过智能技术生成

内存泄露是Java听到最多的关于内存的事了,这篇文章就来谈谈这件事。

内存泄露与资源泄露

什么是泄露?泄露在计算机语境下,通常指的是某个资源无法被访问,也无法被释放。

内存泄露一般发生在某个对象的引用丢失,无法再访问到该引用,但是该引用却依旧引用着某个对象,导致这个对象无法回收,最终导致内存溢出OOM。

资源泄露一般发生在连接池,IO流等场景,如从连接池中每次都新建连接但不关闭,每次都打开新的IO流但不关闭,等等情况。

内存泄露发生的情况

内存泄露多发生于static的集合中,比如当你定义了一个static HashMap,此时将某个key-value放入其中后,方法段结束。

这时,除非调用map的clear方法,否则显然该value将无限持有对象的引用,无法释放。

这种写法看似可笑,却很难避免,尤其在大量框架代码中,反而更容易发生,因为大部分框架代码对业务代码的增强,都是通过AOP方式来做的,此时对业务代码来说,这类隐式的static Map难以防范。

确认是否是内存泄漏

内存使用过高,一定是内存泄露吗?

内存使用过高,并不一定是内存泄露导致的结果,具体要看内存堆的分析。

一般内存泄露最直观的体现就是:

  • 内存使用高;

  • GC回收不了内存,即GC前后堆大小几乎无变化;

  • JVM疯狂GC,CPU打满;

  • Java进程触发Linux操作系统的OOM-killer,Java进程被杀死;

  • 或者CPU被GC任务打满,服务器实际宕机。

但是这不一定是泄露导致的,也有可能是内存的错误使用导致的,不过大同小异,主要还是需要排查异常内存的使用。

之所以作者这么说,是因为作者曾经在线上遇到了架构组修改日志框架,错误的将日志内容作为了key存入了map,本应的key-value应该为traceId-日志内容,结果架构组却将key-value搞反了,导致大量的巨大key打满了内存,堆dump文件里全是几十k几十k的字符串。

如何避免内存泄露

根据上面说的内存泄露多数发生的情况,避免内存泄露的策略也就十分简单了。

  • 尽量使用局部变量;

  • 减少使用static集合;

  • 如果必要的使用static集合,尽量使用弱引用等低级引用。

内存泄露问题如何排查

内存泄露或内存持续使用较高时,通常通过堆的情况来排查。

首先可以通过jmap -histo:live pid|less 命令,查看堆内对象使用情况。

此时如果内存泄露,一般都是会某个基本类型对象过多,然后可以与正常的服务作对比,看哪个对象的数量异常的多,此时如果可以判断出来,也没必要dump了。

如果通过jmap无法断定,则可以使用jmap -dump:live,format=b,file= 命令,生成dump文件。

将dump文件通过java原生的软件或者eclipse的mat工具,就可以看到哪些对象占用过多,此时你应该关注的是非基本类型对象的其他对象,因为一般来说都是基本类型的数量和大小最多。

一般来说,你会看到以下现象:

  • 某个map的Node十分多,有几十万个;

  • 某个框架的某个对象十分多;

  • char数据,也就是C[],占用十分多,因为有很多大字符串。

最后:下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

全部资料获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值