千家信息网

如何探究ThreadLocal内存泄漏的原因

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇文章给大家分享的是有关如何探究ThreadLocal内存泄漏的原因,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、首先看下Thre
千家信息网最后更新 2026年11月02日如何探究ThreadLocal内存泄漏的原因

本篇文章给大家分享的是有关如何探究ThreadLocal内存泄漏的原因,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

1、首先看下ThreadLocal的原理图:

在ThreadLocal的生命周期中,都存在这些引用。

其中,实线代表强引用,虚线代表弱引用;

2、ThreadLocal的实现:每个Thread维护一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal实例本身,value是真正需要存储的Object;

3、也就是说ThreadLocal本身不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value,值得注意的是图中的虚线,表示ThreadLocalMap是使用ThreadLocal的弱引用作为key,其在GC时会被回收;

4、ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,造成内存泄漏。

5、总的来说就是,ThreadLocal里面使用了一个存在弱引用的map, map的类型是ThreadLocal.ThreadLocalMap. Map中的key为一个threadlocal实例。这个Map的确使用了弱引用,不过弱引用只是针对key。每个key都弱引用指向threadlocal。当把threadlocal实例置为null以后,没有任何强引用指向threadlocal实例,所以threadlocal将会被gc回收。

但是,我们的value却不能回收,而这块value永远不会被访问到了,所以存在着内存泄露。因为存在一条从current thread连接过来的强引用。只有当前thread结束以后,current thread就不会存在栈中,强引用断开,Current Thread、Map value将全部被GC回收。最好的做法是将调用threadlocal的remove方法,这也是等会后边要说的。

6、其实,ThreadLocalMap的设计中已经考虑到这种情况,也加上了一些防护措施:在ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。这一点在上一节中也讲到过!

7、但是这些被动的预防措施并不能保证不会内存泄漏:

a、使用static的ThreadLocal,延长ThreadLocal的生命周期,可能导致内存泄漏;

b、分配只用了ThreadLocal又不再调用get()、set()、remove()方法,那么可能导致内存泄漏,因为这块内存会一直存在;

以下是源码:

/**
* The entries in this hash map extend WeakReference, using
* its main ref field as the key (which is always a
* ThreadLocal object). Note that null keys (i.e. entry.get()
* == null) mean that the key is no longer referenced, so the
* entry can be expunged from table. Such entries are referred to
* as "stale entries" in the code that follows.
*/
static class Entry extends WeakReference> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal k, Object v) {
super(k);
value = v;
}
}

以上就是如何探究ThreadLocal内存泄漏的原因,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

内存 实例 线程 原因 代表 只是 周期 就是 指向 措施 方法 时候 更多 生命 知识 篇文章 虚线 存储 实用 这样一来 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网中国科技 科技制造互联网公司 互联网 科技馆 中国的互联网科技企业的崛起 重庆威客帮互联网科技 南山科技园互联网公司有哪些 亳州好赞互联网科技有限公司 互联网科技人工智能实验室 西安小鹰速贷互联网科技有限公司 用友工业互联网科技发展 互联网方面的科技前沿 互联网金融科技公司的优势 互联网企业科技类企业如何做账 城市宝互联网科技有限公司 互联网相关科技技术 有人说阿里系是互联网科技企业 陕西云淼互联网科技公司 宁波跨境商互联网科技有限公司 互联网时代高科技布局 杭州融税互联网科技有限公司 科技金融是不是互联网金融 科技企业和互联网企业 亿账通互联网科技 互联网科技视频素材 南平创想时代互联网科技有限公司 中国科技创新与世界互联网大会 允成互联网科技有限公司融资 互联网科技融合创新 新氧科技和美国互联网有关系吗 科技信息时代互联网发展
0