原理
- ThreadLocal 通过 ThreadLocalMap 对象存取数据
- ThreadLocalMap 是放在 Thread 对象里的
- ThreadLocal 对象作为 ThreadLocalMap 对象的键来使用,采用弱引用的方式使用。
内存泄漏的原因
因为 ThreadLocalMap 里 ThreadLocal 对象是弱引用,当没有强引用指向 ThreadLocal 对象时,在下次 GC 时,ThreadLocal 对象会被回收,这样 ThreadLocalMap 对象里就出现 key 为 null value 不为空的数据,这些数据永远不会被用到,这样就造成了内存泄漏。
一般而言,ThreadLocal 提供了清理机制,当调用 ThreadLocal 的 get, set, remove
方法时会自动清理 ThreadLocalMap 里 key 为 null 的键值对,但如果不再调用这些方法,就会造成内存泄漏,影响范围是在线程生命周期内。尤其是在线程池的情况下,线程对象会重复使用,生命周期很长,这样 ThreadLocal 对象不仅会造成内存泄漏,还可能引起业务问题。
应对方法
每次用完 ThreadLocal 对象都调用它的 remove
方法清除数据。