聊一聊ThreadLocal内存泄漏的问题

article/2025/8/19 11:02:21

回答任何一个问题的时候应该要遵循:明确题意-->深入浅出-->举例说明-->总结,这四个步骤很重要,可以让你沉着冷静,思路清晰,避免尴尬。

01 —  明确题意

明确题意的意思就是先明确一下面试官的题目,能避免自己理解有误而跑题,可以这样说:ThreadLocal内存泄漏的原因主要是因为ThreadLocal中包含了ThreadLocalMap,然而ThreadLocalMap的对象是在Thread中的,如果Thread没有结束,则ThreadLocalMap一直不会释放,假如ThreadLocalMap中设置了很多值,而且没有手动设置remove(),则可能会造成内存泄露。网上有些网友的答案是因为ThreadLocal作为一个弱引用的key然后造成每次GC的时候会回收掉ThreadLocal,导致无法访问value,然后造成了内存泄漏,这是完全错误的,其实和弱引用没有关系。

02 — 深入浅出

先思考一下,如果每次GC都把ThreadLocal给回收掉,那么业务代码在运行的时候出现GC,ThreadLocal被回收之后,业务代码就会获取不到值,这样就会出现问题。弱引用的定义确实是在GC的时候就会被回收掉,如果ThreadLocal又被其它强引用指向了,则它是不会被回收的,想想我们在使用ThreadLocal的时候,我们是怎么定义并使用他的呢?

可以看到threadLocal可以定义为一个全局的静态变量或者是一个局部变量,threadLocal是强引用,不管怎么样它都不会被回收掉,只是又将它的引用又给到了ThreadLocalMap中的Entry.key中,虽然这个key是弱引用,但是ThreadLocal对象是不会被回收的。

如果一个线程Thread结束了,那么Thread里面的threadLocals将会被回收掉,也就是ThreadLocalMap数据结构会被回收掉,也就不会出现内存泄漏的问题。那出现内存泄露的情况是什么呢?

当Thread一直没有结束时,Thread中的threadLocals就不会被回收,threadLocals里面存储的Entry如果不手动删除的话,就会一直存在这个threadLocals里面,所以就会出现内存泄漏的问题,通常在线程池的情况下,一个Thread会使用很长时间,如果在使用的过程中,一直向里面设置Entry,也就是key = ThreadLocal 和 value=业务对象,如果一个线程的任务执行完毕之后,没有手动设置remove()方法释放掉这个Entry的话,那么Thread的threadLocals中的Entry将会一直膨胀,一直停留在Thread中的threadLocals中,造成内存泄漏,所以一定要手动设置remove()。

那这会延伸出来另外一个问题,为什么使用弱引用?

弱引用的作用就是当出现GC的时候会回收这些弱引用的对象,如果有些业务不是定义的全局的静态变量而是局部的变量,例如:通过ThreadLocal保存一些在整个线程中全局都可以使用的变量,减少方法与方法调用的参数传递。此时当一个任务执行完成之后,可以将ThreadLocal设置成为null,局部变量的强引用就会失效,存在Map中的Entry的key只有弱引用,如果不进行清理的话,则会出现内存泄漏的问题,此时出现GC的时候就会回收掉ThreadLocal对象,也就是说ThreadLocal是尽量的去避免内存泄漏的问题。但是解决不了根本的问题,所以需要开发人员手动去调用remove()方法才能够彻底解决内存泄漏的问题。

03 — 举例说明

找到了一个开源项目ruoyi框架的源码,可以看到ThreadLocal是一个全局的静态变量,不同的线程不会影响彼此,ThreadLocal永远不会被回收掉,在线程池的情况下,当我们操作完之后,需要手动调用remove()方法,上图也提供了clearDataSourceType()方法用来清除任务执行完之后的Entry对象。

可以看到在Aspect切面中的around方法中,最终调用了此方法。

04 — 总结

最后来句总结:这就是我对ThreadLocal内存泄漏的理解。主要的作用是提醒面试官说完了,看看面试官是否有问题要问,或者让面试官提问下一个问题,不要让面试官或者自己尴尬。

                   


http://chatgpt.dhexx.cn/article/KgyDpEXK.shtml

相关文章

聊一聊Https

前言 https协议是一种在http的基础上进行加密的协议,在http协议传输过程中,传输的数据都是已明文的方式进行传输,那我们的信息就有可能被他人进行捕获篡改(比如你给女神表白却被程序员情敌发现并修改了你的消息,然后你…

SLAM基础——聊一聊信息矩阵

文章目录 前言1 :book: 信息矩阵1-1 :bookmark: 信息矩阵是什么?有什么作用?1-2 :bookmark: 信息矩阵与Hessian矩阵的关系1-2-1 Hessian矩阵和H矩阵的关系1-2-2 Hessian或H矩阵和信息矩阵的关系 2 :book: 信息矩阵与最小二乘的关联2-1 :bookmark: 先谈一…

聊一聊SpringCloud的五大组件

聊一聊SpringCloud的五大组件 1.初始SpringCloud 微服务是一种架构方式,最终肯定需要技术架构去实施。 微服务的实现方式很多,但是最火的莫过于Spring Cloud了。为什么? 后台硬:作为Spring家族的一员,有整个Spring全…

聊一聊Serverless

聊一聊Serverless Serverless是什么云计算发展过程Serverless的优势Serverless的不足云函数冷启动热启动函数实例不同语言冷启动时长排名首次调用超时性能优化 SFFBaaS再会推荐阅读 Serverless是什么 从单词角度理解,server译为服务,less译为少,Serverl…

聊一聊C语言位域/位段

目录 1、概念和定义 2、实例 在做嵌入式开发的时候,我们经常会遇到这样的代码: struct {unsigned int widthValidated : 1;unsigned int heightValidated : 1; } status; 这样定义结构体变量是什么意思呢? 主要原因是:有些信…

【毕业季】今天简单聊一聊这几个问题

今天简单聊一聊这几个问题 我又来参加活动啦~ 活动地址:毕业季进击的技术er 首先我看了下活动模板,有三个身份,| 毕业生 | 在校生 |职场人 ,现在呢其实我们应该还算是在校生,但是我们是大三,也可以说是大四…

聊一聊差分放大器

目录 1、共模抑制比(CMRR) 2、低容差电阻 3、高噪声增益 4、单电容滚降 5、运算放大器输入端之间的电容 大学里的电子学课程说明了理想运算放大器的应用,包括反相和同相放大器,然后将它们进行组合,构建差动放大器…

简单聊一聊单点登录

单点登录 一、单点登录二、演示步骤①简单结构(域名的设置)②创建项目1.sso-server 模块代码LoginController代码如下GulimallTestSsoServerApplication启动类代码login.html代码application.properties配置文件pom.xml文件 2.sso-client1模块代码HelloController代码GulimallT…

聊一聊俞敏洪

2009年,CCTV颁发中国经济年度人物,给出了这样的颁奖词: “一个曾经的留级生,让无数学子的人生升级;他从未留过洋,却组建了一支跨国的船队。他用26个字母拉近了此岸和彼岸的距离。胸怀世界,志在东…

闲暇聊一聊

大家好,我是Tom哥 非常庆幸,早毕业了几年,那时的互联网还没有像现在这么卷,甚至没有 内卷 这个网络流行词 一切都是那么美好,可以自由享受学习技术的快乐 Tom哥是校招进的阿里,当时的技术资料可不像现在…

聊一聊数据库的行存与列存

目录 存储方式比较 优缺点比较 行存与列存实验 选择建议 注意事项 好多人最开始学习数据库的时候,是关系数据库,数据以表格形式存储,一行表示一条记录。其实这种就是典型的行存储(Row-based store),将…

聊一聊 AS 的一些好用的功能

聊一聊 AS 的一些好用的功能 文章开始前先墨迹几句,好久没写文章了,这段时间公司确实挺忙,也没抽出时间,上一篇文章还是三月初写的,距今已经两个多月啦,不能再这样下去了,虽然我不能像一些大佬…

聊一聊罗振宇

小灰是得到平台的重度用户,也是罗振宇的粉丝。 罗振宇,人称“罗胖子”,非常有趣的是,人们常常把另一个姓罗的胖子和他混为一谈。 今天,我们就来聊一聊他。 罗振宇是个特别复杂的人。 很多人认识罗振宇,是从…

聊一聊我的2020

回顾2020 (接下来是一大段唠叨,可以直接到文末,有小安利和经验总结) 还有几天2020年就结束并迎来新的一年。这一年中总是能听到有人在感慨2020是不平凡的一年。仔细想想,确实如此,至少对我来说是这样的。 作…

聊一聊 gRPC 中的拦截器

今天我们继续 gRPC 系列。 前面松哥跟大家聊了 gRPC 的简单案例,也说了四种不同的通信模式,感兴趣的小伙伴可以戳这里: 一个简单的案例入门 gRPC 聊一聊 gRPC 的四种通信模式 今天我们来继续聊一聊 gRPC 中的拦截器。 有请求的发送、处理&…

聊一聊微博新知博主这件事,看看赚钱方式有哪些?

从今天开始,准备将我付费星球内的精华文章,在每周六和周日以付费文章的方式在公众号分享给大家,如果你不想加入我的星球,还想看的话,可以在这里付费看。当然,加入星球会更划算,因为星球内内容更…

【QGIS入门实战精品教程】2.1:初识QGIS软件

从今天开始,我们一起来学习一款免费开源、对机器要求低、功能强大的GIS软件:QGIS ! 一、QGIS简介 QGIS(原称Quantum GIS)是一个自由软件的桌面GIS软件。它提供数据的显示、编辑和分析功能。 QGIS是一个用户界面友好的…

QGIS教程01:为什么要用QGIS?

从去年开始抛弃ArcGIS转用QGIS以来,发现QGIS越来越好用,功能也相当强大。而且我发现身边好多朋友也在开始使用QGIS,但目前国内这方面的学习资料还比较少,国外的原版资料又相对比较啰嗦,所以我和几位GISer入门知识星球的…