百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Java内存泄漏最全详解(6大原因及解决方案)

liuian 2025-05-27 15:54 69 浏览

大家好,我是mikechen。

内存泄漏是经常出现的线上故障,也是大厂面试经常考察的,下面我就全面来详解内存泄漏以及解决方案@mikechen

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

什么是内存泄漏

内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。

随着垃圾回收器活动的增加以及内存占用的不断增加,程序性能会逐渐表现出来下降,极端情况下,会引发OutOfMemoryError导致程序崩溃。


内存泄漏的原因

JVM 虚拟机是使用引用计数法和可达性分析来判断对象是否可回收,本质是判断一个对象是否还被引用,如果没有引用则回收。

在开发的过程中,由于代码的实现不同就会出现很多种内存泄漏问题,让gc 系统误以为此对象还在引用中,无法回收,造成内存泄漏。

内存泄漏的危害

  • 长时间运行,程序变卡,性能严重下降
  • 程序莫名其妙挂掉
  • OutOfMemoryError错误
  • 乱七八糟的错误,还不易排查


内存泄漏有哪些情况

内存泄漏原因很多,因此这里给出最常见的几种。

1.资源未关闭造成的内存泄漏

各种连接,比如数据库连接、网络连接和IO连接等。

在对数据库进行操作的过程中,首先需要建立与数据库的连接,当不再使用时,需要调用close方法来释放与数据库的连接。

只有连接被关闭后,垃圾回收器才会回收对应的对象。否则,如果在访问数据库的过程中,对Connection、Statement或ResultSet不显性地关闭,将会造成大量的对象无法被回收,从而引起内存泄漏,因此最好按照下面的做法处理资源类,伪代码如下:

publicvoidhandleResource {
try {
// open connection
// handle business
} catch (Throwable t) {
// log stack
} finally {
// close connection
}}


2.静态集合类

如HashMap、LinkedList等等,如果这些容器为静态的,那么它们的生命周期与程序一致,则容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏。

生命周期长的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。

3.ThreadLocal的误用

ThreadLocal一定要列在Java内存泄露的榜首,总能在不知不觉中将内存泄露掉,一个常见的例子是:

publicvoidtestThreadLocalMemoryLeaks {
ThreadLocal<List<Integer>> localCache = new ThreadLocal<>;
List<Integer> cacheInstance = new ArrayList<>(10000);
localCache.set(cacheInstance);localCache = new ThreadLocal<>;
}

当localCache的值被重置之后cacheInstance被ThreadLocalMap中的value引用,无法被GC。

但是其key对ThreadLocal实例的引用是一个弱引用,本来ThreadLocal的实例被localCache和ThreadLocalMap的key同时引用,但是当localCache的引用被重置之后。

则ThreadLocal的实例只有ThreadLocalMap的key这样一个弱引用了,此时这个实例在GC的时候能够被清理。

上面这张图详细地揭示了ThreadLocal和Thread以及ThreadLocalMap三者的关系。

1)Thread中有一个map,就是ThreadLocalMap

2)ThreadLocalMap的key是ThreadLocal,值是我们自己设定的。

3)ThreadLocal是一个弱引用,当为null时,会被当成垃圾回收

重点来了,突然我们ThreadLocal是null了,也就是要被垃圾回收器回收了,但是此时我们的ThreadLocalMap生命周期和Thread的一样,它不会回收,这时候就出现了一个现象。

那就是ThreadLocalMap的key没了,但是value还在,这就造成了内存泄漏。

解决办法:使用完ThreadLocal后,执行remove操作,避免出现内存溢出情况。

4.变量不合理的作用域

一般而言,一个变量的定义的作用范围大于其使用范围,很有可能会造成内存泄漏。另一方面,如果没有及时地把对象设置为null,很有可能导致内存泄漏的发生。

public class UsingRandom {
private String msg;
public void receiveMsg(){
readFromNet();// 从网络中接受数据保存到msg中
saveDB();// 把msg保存到数据库中
}
}

如上面这个伪代码,通过readFromNet方法把接受的消息保存在变量msg中,然后调用saveDB方法把msg的内容保存到数据库中,此时msg已经就没用了,由于msg的生命周期与对象的生命周期相同,此时msg还不能回收,因此造成了内存泄漏。

实际上这个msg变量可以放在receiveMsg方法内部,当方法使用完,那么msg的生命周期也就结束,此时就可以回收了。还有一种方法,在使用完msg后,把msg设置为null,这样垃圾回收器也会回收msg的内存空间。

5.内部类持有外部类

如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。

6.堆外内存无法回收

堆外内存不受gc的管理,可能因为第三方的bug出现内存泄漏

内存泄漏的解决办法

1.少使用静态变量

尽量减少使用静态变量,或者使用完及时 赋值为 null;

2.明确对象有效作用域

明确内存对象的有效作用域,尽量缩小对象的作用域,能用局部变量处理的不用成员变量,因为局部变量弹栈会自动回收;

3.注意声明周期引用

减少长生命周期的对象持有短生命周期的引用;

4.注意Sting的使用

使用StringBuilder和StringBuffer进行字符串连接,Sting和StringBuilder以及StringBuffer等都可以代表字符串,其中String字符串代表的是不可变的字符串,后两者表示可变的字符串。

如果使用多个String对象进行字符串连接运算,在运行时可能产生大量临时字符串,这些字符串会保存在内存中从而导致程序性能下降。

5.不需要对象手动设置Null

对于不需要使用的对象手动设置null值,不管GC何时会开始清理,我们都应及时的将无用的对象标记为可被清理的对象;

6.及时关闭各种链接

各种连接(数据库连接,网络连接,IO连接)操作,务必显示调用close关闭。

以上

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

相关推荐

windows7如何清理c盘(win7怎么清理c盘)

1.打开桌面计算机,右键点击“C盘”,并选取“属性”。2.待新窗口弹出后,依次点击“工具”、“立即进行碎片整理”。3.最后,选取C盘,在按下“磁盘碎片整理”按钮,系统就会对C盘进行分析,并进行整理。4...

win10自带分区工具(win10官方分区工具)

Win10自带的分区工具是磁盘管理器,可以用来创建、删除、格式化和调整磁盘分区。下面是使用磁盘管理器分区的步骤:1.打开磁盘管理器。您可以在Windows10搜索栏中输入“磁盘管理器”来快速打开。...

appstore正版下载软件(apple store下载正版)

不会,他是正版的,因为只有ios系统可以用,但他里面的好游戏都是要收费的,所以打架都要越狱,去其它地方下载,不去商店的在安卓上,GooglePlayStore是类似于苹果的AppStore一...

手机锁屏密码键盘没了(手机输入密码的键盘没了怎么办)

如果手机锁屏密码的键盘找不到,首先要确认是否是由于软件问题导致的。可以尝试重启手机或者清理手机缓存来解决。如果问题仍然存在,可以尝试更换输入法或者恢复手机出厂设置来解决。如果以上方法都没有效果,建议联...

移动硬盘跟固态硬盘的区别(移动硬盘跟固态硬盘的区别是什么)

一:移动硬盘移动硬盘是指以传统机械磁盘作为存储介质,用于计算机之间交换大容量数据,讲究移动便携性的存储产品。优点:具有容量大、价格便宜的特点,方便存储大量文件数据。(推荐学习:web前端视频教程)缺...

windows怎么截图快捷键(windows截图快捷键没反应)

1、按Prtsc键截图这样获取的是整个电脑屏幕的内容,按Prtsc键后,可以直接打开画图工具,接粘贴使用。也可以粘贴在QQ聊天框或者Word文档中,之后再选择保存即可。2、按Ctrl+Prtsc键截图...

显示器分辨率有哪几种(显示器屏幕分辨率都有哪些)

目前使用较多的显示器分辨率有640*480,800*600,1024*768,1280*1024四种。刷新率,这主要是指显示器显示画面每秒刷新的次数,现在的电脑显示屏刷新率一般为75Hz,如果刷新率在...

小马激活工具网址(小马激活工具是什么东西)
  • 小马激活工具网址(小马激活工具是什么东西)
  • 小马激活工具网址(小马激活工具是什么东西)
  • 小马激活工具网址(小马激活工具是什么东西)
  • 小马激活工具网址(小马激活工具是什么东西)
windows7激活工具 知乎(win7激活工具怎么使用教程)

Win7激活工具有很多,比如kms激活工具、小马激活工具、Windowsloader等。下面以这三款激活工具为例,做一个简单的比较。1、kms激活工具,相对比较稳定,通用性强,对各种gho、iso镜...

英伟达高端显卡排行(英伟达最高级显卡)

具体的排名如下:1、NVIDIAGeForceRTX30902、NVIDIAGeForceRTX3080Ti3、NVIDIAQuadroRTXA60004、NVIDIAGeFor...

苹果电脑为啥不能玩游戏(买苹果电脑的十大忠告)

1、MacBook本身就不是用来玩游戏的,是用来轻度办公的,只有集成显卡没有独立显卡,玩游戏也会非常卡。2、MacOS系统虽然支持steam软件,但是里面的游戏并不支持MacOS,况且本身支持MacO...

笔记本电脑显卡驱动怎么安装

使用驱动精灵或者驱动之家搜索驱动,下载后会自动安装驱动的。您好,以下是安装MacBook独立显卡驱动的步骤:1.打开“应用程序”,找到“实用工具”文件夹,打开“终端”。2.在终端窗口中输入以下命令...

家庭wifi已连接不可上网(家里wifi已连接不可用是什么原因)

WiFi已连接不可上网原因和解决方法一、路由器不稳定有些无线路由器、光猫(宽带猫)的质量比较差,长时间运行后会出现死机等一系列的问题。解决办法:把你家里的无线路由器、光猫(宽带猫)断电,等待几分钟,然...

win10专业版在哪下(win10专业版在哪下载)

1.登陆MicroSoft官方网站会员中心,https://insider.windows.com/?lc=1033,点击“登陆”。2.使用hotmail邮箱或者开发者帐号登陆即可。3.选择“获...

中国杀毒软件十大排名(杀毒软件十大排名电脑有哪些)

第一名:火绒安全软件免费下载优点:口碑最好、安静、轻巧、界面简洁、无广告弹窗、无捆绑其他软件、占用内存少。缺点:我杀毒不行、不要紧张,我防毒也不行。第二名:腾讯电脑管家免费下载优点:我从良了...