ThreadLocal内存泄漏的缘故
2021/10/24 7:11:30
本文主要是介绍ThreadLocal内存泄漏的缘故,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
我们通常会用ThreadLocal用来存储当前线程的数据。但是在实际使用的时候注意使用完之后及时调用实例的remove方法。
他把数据绑定到当前线程代码原理是这么干的。
首先Thread类里面存储ThreadLocalMap。
然后ThreadLocalMap是ThreadLocal的内部类。
可以看到ThreadLocalMap里面entry是以ThreadLocal作为key值的。
他存储数据到当前线程是这么干的。
相当于ThreadLocal本身不存储数据,而是作为key放在其内部类ThreadLocalMap中,数据作为value放在ThreadLocalMap中。
要取数据的时候。通过当前线程获取其ThreadLocalMap,然后根据threadlocal实例获取对应的数据。
从上面可以看出,ThreadLocalMap是里面entry是以ThreadLocal作为key值的,而且还是弱引用的。意味着下次gc的时候,不管jvm堆内存是否足够,threadlocal都会被回收掉,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,造成内存泄漏。
我们复现一下ThreadLocal内存泄漏的现象。
public class Test { public static void main(String[] args) { new Thread(() -> { // ThreadLocal放置到代码块中,为证明threadLocal 会被GC回收掉 { ThreadLocalTest<ValueVO> threadLocal = new ThreadLocalTest<>(); threadLocal.set(new ValueVO()); System.out.println(threadLocal.get()); } int i = 0; while (true) { try { Thread.sleep(1000); //每秒加10M 堆内存 能看出内存增长趋势 //GC时,a临时变量会被回收 int[] a = new int[1024 * 1024 * 10]; if (i++ > 100) { break; } i++; } catch (InterruptedException e) { } } }).start(); } } class ValueVO { @Override public String toString() { return "hello,world"; } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("value deading"); } } /** * 继承ThreadLocal,实现finalize方法,垃圾回收器准备释放内存的时候,会先调用finalize()。 * * @param <T> */ class ThreadLocalTest<T> extends ThreadLocal<T> { @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("key deading"); } }
然后发现ThreadLocalMap的作为key值的ThreadLocal被垃圾回收了,作为value的当前线程的ValueVo的数据最后都没被回收。
解决办法:每次使用完ThreadLocal,都调用它的remove()方法,清除数据。
这篇关于ThreadLocal内存泄漏的缘故的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-11国产医疗级心电ECG采集处理模块
- 2025-01-10Rakuten 乐天积分系统从 Cassandra 到 TiDB 的选型与实战
- 2025-01-09CMS内容管理系统是什么?如何选择适合你的平台?
- 2025-01-08CCPM如何缩短项目周期并降低风险?
- 2025-01-08Omnivore 替代品 Readeck 安装与使用教程
- 2025-01-07Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
- 2025-01-06PingCAP 连续两年入选 Gartner 云数据库管理系统魔力象限“荣誉提及”
- 2025-01-05Easysearch 可搜索快照功能,看这篇就够了
- 2025-01-04BOT+EPC模式在基础设施项目中的应用与优势
- 2025-01-03用LangChain构建会检索和搜索的智能聊天机器人指南