§2.2.3 ThreadLocal原理与内存泄漏
考察意图:是否理解ThreadLocal的实现原理、内存泄漏成因及规避方式。
回答样板:
每个Thread内部维护一个ThreadLocalMap,key是ThreadLocal实例的弱引用(WeakReference),value是线程持有的值。
内存泄漏原因:在线程池场景下线程复用,ThreadLocal使用完没有调用remove()时——key(ThreadLocal实例)会被GC回收(弱引用特点),但value的强引用链依然存在(Thread → ThreadLocalMap → Entry → value),导致value无法被回收,造成内存泄漏。
规范:ThreadLocal使用完必须在finally块中调用remove()。
| |
追问预判:
追问:“为什么ThreadLocalMap的key要设计成弱引用?”
设计为弱引用的目的是:当ThreadLocal对象不再被外部强引用时(即使用方不再需要它了),GC可以回收ThreadLocal实例,使得对应的Entry(key=null)成为无效条目。下次ThreadLocalMap调用set/get/remove时会主动清理这些key为null的Entry。如果没有这一层弱引用设计,即使外部不再使用ThreadLocal,Entry和value也会一直存活,导致更严重的内存泄漏。
陷阱提示:答不出弱引用设计意图;只知道"用ThreadLocal存用户信息"但说不清泄漏原理。