一、弱引用
只要垃圾回收机制一运行,不管 JVM 内存空间是否充足,都会回收该对象占用的内存。
二、ThreadLocal底层原理
ThreadLocal为共享变量在每个线程中创建一个副本,每个线程都可以访问自己内部的副本变量。通过threadlocal 保证线程的安全性。在 ThreadLocal 类中有一个静态内部类 ThreadLocalMap(其类似于 Map),用键值对的形式存储每一个线程的变量副本,ThreadLocalMap 中元素的 key 为当前ThreadLocal 对象,而 value 对应线程的变量副本。ThreadLocal 本身并不存储值,它只是作为一个 key 保存到 ThreadLocalMap中,但是这里要注意的是它作为一个 key 用的是弱引用,因为没有强引用链,弱引用在 GC的时候可能会被回收。
这样就会在 ThreadLocalMap 中存在一些key为null的键值对(Entry)。因为 key 变成 null 了,我们是没法访问这些 Entry 的,但是这些 Entry 本身是不会被清除的。如果没有手动删除对应 key 就会导致这块内存即不会回收也无法访问,也就是内存泄漏。使用完 ThreadLocal之后,记得调用 remove方法。
注意: 在不使用线程池的前提下,即使不调用 remove 方法,内存也不会泄露。因为是ThreadLocal是弱引用,线程的"变量副本"也会被gc回收,即不会造成内存泄漏的情况。