文章目录
概要
一说到TheadLocal首先想到的是线程安全,其次是内存泄漏.内存泄漏是因为弱引用导致,弱引用在GC的时候key会被回收,但是value没有被回收,这样就会导致value一直占用内存空间内存泄漏.不知道大家第一次看到这个概念时有没有这样一个疑惑? 我前脚刚用TheadLocal设置一个值,后脚GC就给清了,那后面我不是用不了?那这种设计不是有毛病?其实不然,往下看.
测试代码
@RestController
public class DemoController {
@RequestMapping("/test1")
public void test1() throws Exception {
Node node = new Node("xxx");
// 强引用
ThreadLocal<Node> test = new ThreadLocal<>();
test.set(node);
// 此时gc 无法回收 threadLocalMap entry table 的 弱引用 key
System.gc();
// 等待gc 调度
Thread.sleep(60000);
// 用来debug查看 threadLocalMap 中entry table情况
ThreadLocal<Node> test23 = new ThreadLocal<>();
Node node23 = new Node("xxx1");
test23.set(node23);
// 置空 断开强引用
test = null;
System.gc();
Thread.sleep(60000);
// 用来debug查看 threadLocalMap 中entry table情况
ThreadLocal<Node> test24 = new ThreadLocal<>();
Node node24 = new Node("xxx2");
test24.set(node24);
}
}
测试场景
场景一: 触发GC但ThreadLocal不置为空
结果: ThreadLocal 没有被回收
场景二: 触发GC但ThreadLocal置为空
结果: ThreadLocal 被回收了
小结
当且仅当ThreadLocal只有弱引用时触发GC时ThreadLocal会被回收.
如果ThreadLocal是全局变量用来储存用户登录信息等此时是ThreadLocal有强引用不会被回收.