当前位置:网站首页>ThreadLocal内存泄漏问题讲解
ThreadLocal内存泄漏问题讲解
2022-08-04 05:35:00 【阿里巴巴首席技术官】
一、首先回顾一下内存泄漏是什么:
内存泄漏是指:程序已经不再使用某字段、某对象。但是却无法回收掉它占用的内存。
两个关键点:不再使用 并且 无法回收
二、为什么ThreadLocal会发生内存泄漏问题?
2.1 问题发现
以下是整体结构
ThreadLocal就相当于一个访问工具类,通过操作ThreadLocal对象的方法 来操作存储在当前线程内部的ThreadLocalMap里的值
ThreadLocalMap是一个哈希数组,key为ThreadLocal对象,Value为一个Object类型的值
这就意味着可以创建多个ThreadLocal来获取不同ThreadLocal往这个Map里存的值
调用ThreadLocal.get() 方法的时候,会将当前ThreadLocal对象传过去,所以可以获取到指定ThreadLocal设置到当前线程的值
问题:ThreadLocal被回收了
此时就没有方式能够访问到val了,所以val就是不会再被程序用到,但是由于Thread还存在就无法回收,那么此时便存在了内存泄漏!
对应的简单示例代码如下
可以发现问题,ThreadLocal已经被清理掉了,代表现在已经没有方式去访问当前ThreadLocal存到Map里的value数据了
但是当前线程由于还在执行、没有关闭,所以内部的value还一直存在!
此时 造成内存泄漏
2.2 ThreadLocal的防御机制
官方也认识到了这个问题,所以Map的key设置为了弱引用
所以现在会变成这个样子,当ThreadLocal被清理掉了。Key无人引用后,就会被gc清理掉,因为他是弱引用,key变为null了,代表此时value需要被清理了。这个时候调用set、get、remove方法时都会触发清理机制(监测key==null就清理value)
而如果key是强引用,就不知道是不是没人引用这个值了,就不知道要不要清理。
当然了,如果Thread线程先于ThreadLocal被回收掉,就不会有这个问题了
三、解决办法
在使用完数据后即使调用remove() 清理掉就行了
边栏推荐
猜你喜欢
随机推荐
对渗透测试工程师来说,学历重要嘛?
Database: Organize Four Practical SQL Server Scripting Functions
Microsoft Store 微软应用商店无法连接网络,错误代码:0x80131500
DropBlock: 卷积层的正则化方法及复现代码
ffmpeg打开rtsp流应该设置的几个参数
sql常用函数
新冠病毒和网络安全的异同及思考
数据库JDBC DAO层方法
狗都能看懂的Self-Attention讲解
Jackson 使用样例
golang rtsp拉流测试
解决腾讯云DescribeInstances api查询20条记录以上的问题
桌面右键的NVIDIA去除与恢复
CMDB 腾讯云部分实现
树莓派 4 B 拨动开关控制风扇 Rasberry Pi 4 B Add Toggle Switch for the Fan
2DCNN, 1DCNN, BP, SVM fault diagnosis and result visualization of matlab
mysql:列类型之float、double
Faster - RCNN principle and repetition code
无一技之长学什么可以做到月入上万?
基于时序模式注意力机制(TPA)的长短时记忆(LSTM)网络TPA-LSTM的多变量输入风电功率预测