ThreadLocal源码图解

为何ThreadLocalMap.Entry的key需要被包装成WeakReference
复习引用类型
- 强引用(不解释)
- 软引用 SoftReference 如果内存不足,发生GC时可回收
- 弱引用 WeakReference 如果发生GC,会被立即回收
- 虚引用 PhantomReference(自行了解)
看下面代码
ThreadLocal<String> tl = new ThreadLocal<>();
如上代码,new一个ThreadLocal对象,一旦tl被置为null,但是线程内部的ThreadLocalMap.Entry的key依然指向该对象,不就无法做回收动作,所以JDK设计者主动将其包装成WeakReference对象,这样就能保证一旦ThreadLocal对象失去了强引用,即使线程内有引用指向它,依然能够被回收掉
内存泄露产生的原因
如果tl被置为null,但是我们没有在代码做如下动作,就会存在内存泄露的风险
ThreadLocal<String> tl = new ThreadLocal<>();try {tl.set("bingo");//TODO 业务逻辑} finally {tl.remove();//防止内存泄露}
如果tl被置为null,我们又不做tl.remove(),Entry中key指向的ThreadLocal对象被GC回收了,就指向null,但是Entry中value依然被驻留在内存中,这样就造成了内存泄露。
