TheadLocal出现的内存泄漏具体泄漏的是什么?弱引用在里面有什么作用?什么情景什么问题?

首先ThreadLocal是什么就不介绍了!这篇是讲讲里面的东西。

再简单说一下强引用和弱引用,举个例子,我们平常new出来的对象就是强引用的,在栈中有强引用,所以在gc的时候,堆中的实例对象不会被清除掉。

弱引用,如果一个对象只有被弱引用,在发生gc的时候就会被清除掉,原先的弱引用就会指向null。

使用ThreadLoal都有哪些对象会出现泄漏?

1、ThreadLocal对象实例

2、ThreadLocalMap中的Entry对象

3、Entry对象中value的具体指向

具体:

1、ThreadLocal对象实例有两个引用(假如两个都是强引用),一个是栈中的引用,一个是Entry中的key引用。当业务代码执行完,用完ThreadLocal,栈中这个引用关系就清除掉,此时ThreadLocal实例还被key引用,key在Entry中,Entry在ThreadLocalMap中,Map的引用是当前线程,当前线程存在,那么这一系列Map-->Entry-->key,value-->ThreadLocal都不会被清除掉。

所以设计了key是个弱引用,当栈中的强引用关系清除后,key的弱引用随时被gc掉,不会影响ThreadLocal实例对象被清除。

2、在jdk自己解决了ThreadLocal实例内存泄漏的问题了,那么Entry呢?

在前面ThreadLoacl对象被gc了,那么这个key就变成了null。线程、Map一直存在,但是Entry用不到了,也一直被引用着,所以这个需要使用Remove方法,这个方法是将Entry从Map中移除,前提是这个key引用ThreadLocal还在,不然找不到这个Entry。如果都等到ThreadLocal对象被gc掉,那么Map中就会出现很多的key为null的Entry。

所以remove()方法是为了防止Entry对象泄漏的。

在理论是不允许出现key为null的Entry的,但实际上还是避免不了,所以ThreadLocalMap对此也做了优化,ThreadLocalMap在每次调用set()、get()、remove()方法时都会进行清理,以确保不存在key为null的Entry。

但是为了能够及时清理无用的Entry,一定要使用remove方法,不要占着内存,导致大量内存泄漏。

3、在Entry溢出的时候,value自然是溢出的,合理使用remove()方法,避免溢出!

在这里想问一下大家几个问题,一、什么时候会出现栈中ThreadLocal引用关系清除了,但是当前线程还在?

二、如果都不使用remove()方法,线程结束后,ThreadlocalMap会被清除掉吗?还会出现内存泄漏吗?

相关推荐
Wang's Blog6 小时前
Java 项目实战: 交友项目 - 个人资料管理的需求分析与接口设计
java·开发语言·交友
北风toto6 小时前
Linux 服务器如何判断 CPU 是否支持 x86-64-v2 指令集
java·linux·服务器
萧瑟余晖6 小时前
Spring Security综合实战与安全加固详解
java·安全·spring
imDwAaY6 小时前
操作系统如何管理程序运行?从线程、进程到内存隔离与用户态切换:CS162 Note2
android·java·redis
const_qiu6 小时前
第三章 08:3.10 本章小结
java·人工智能
Pniubi6 小时前
快速排序(力扣基础)(递归)
java·数据结构·算法
CarIise7 小时前
Spring MVC 请求参数绑定与常用注解2
java·spring·mvc
七夜zippoe7 小时前
Spring Boot 接通义千问:从拿 Key 到第一个对话接口跑通(保姆级)
java·spring boot·后端
SimonKing7 小时前
别再花钱调 OCR 接口了!这个国产开源工具,免费还能离线跑
java·后端·程序员
Nebula_g7 小时前
SpringBoot企业级实战项目—云禾外卖—SpringBoot常用注解解析
java·网络·数据库·spring boot·后端·spring·javase