TheadLocal GC时一定会被回收?

文章目录

    • 概要
    • 测试代码
    • 测试场景
      • 场景一: 触发GC但ThreadLocal不置为空
      • 结果: ThreadLocal 没有被回收
      • 场景二: 触发GC但ThreadLocal置为空
      • 结果: ThreadLocal 被回收了
    • 小结

概要

    一说到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 没有被回收

TheadLocal GC时一定会被回收?_第1张图片
TheadLocal GC时一定会被回收?_第2张图片

场景二: 触发GC但ThreadLocal置为空

结果: ThreadLocal 被回收了

TheadLocal GC时一定会被回收?_第3张图片
TheadLocal GC时一定会被回收?_第4张图片

小结

   当且仅当ThreadLocal只有弱引用时触发GC时ThreadLocal会被回收.
  如果ThreadLocal是全局变量用来储存用户登录信息等此时是ThreadLocal有强引用不会被回收.

你可能感兴趣的:(小知识,java)