1.为阅读体验,本站无任何广告,也无任何盈利方法,站长一直在用爱发电,现濒临倒闭,希望有能力的同学能帮忙分担服务器成本
2.捐助10元及以上同学,可添加站长微信lurenzhang888,备注捐助,网站倒闭后可联系站长领取本站pdf内容
3.若网站能存活下来,后续将会持续更新内容
要搞懂
ThreadLocal
的底层原理需要看下他的源码,太长了,有兴趣的同学可以自己看看相关资料,这里只是简单介绍下结构,因为Threadlocal
内存泄露是个高频知识点,并且需要简单了解ThreadLocal
结构。
ThreadLocal
的原理可以概括为下图:
从上图可以看出每个线程都有一个ThreadLocalMap
,ThreadLocalMap
中保存着所有的ThreadLocal
,而ThreadLocal
本身只是一个引用本身并不保存值,值都是保存在ThreadLocalMap
中的,其中ThreadLocal
为ThreadLocalMap
中的key
。其中图中的虚线表示弱引用。
这里简单说下Java中的引用类型,Java的引用类型主要分为强引用、软引用、弱引用和虚引用。
- 强引用:发生 gc 的时候不会被回收。
- 软引用:有用但不是必须的对象,在发生内存溢出之前会被回收。
- 弱引用:有用但不是必须的对象,在下一次GC时会被回收。
- 虚引用:无法通过虚引用获得对象,虚引用的用途是在 gc 时返回一个通知。
为什么ThreadLocal会发生内存泄漏呢?
因为ThreadLocal
中的key
是弱引用,而value
是强引用。当ThreadLocal
没有被强引用时,在进行垃圾回收时,key
会被清理掉,而value
不会被清理掉,这时如果不做任何处理,value
将永远不会被回收,产生内存泄漏。
如何解决ThreadLocal的内存泄漏?
其实在ThreadLocal
在设计的时候已经考虑到了这种情况,在调用set()
、get()
、remove()
等方法时就会清理掉key
为null
的记录,所以在使用完ThreadLocal
后最好手动调用remove()
方法。
为什么要将key设计成ThreadLocal的弱引用?
如果ThreadLocal
的key
是强引用,同样会发生内存泄漏的。如果ThreadLocal
的key
是强引用,引用的ThreadLocal
的对象被回收了,但是ThreadLocalMap
还持有ThreadLocal
的强引用,如果没有手动删除,ThreadLocal
不会被回收,发生内存泄漏。
如果是弱引用的话,引用的ThreadLocal
的对象被回收了,即使没有手动删除,ThreadLocal
也会被回收。value
也会在ThreadLocalMap
调用 set()
、get()
、remove()
的时候会被清除。
所以两种方案比较下来,还是ThreadLoacl
的key
为弱引用好一些。
本站链接:https://www.mianshi.online,如需勘误或投稿,请联系微信:lurenzhang888
点击面试手册,获取本站面试手册PDF完整版