强引用、弱引用、软引用和虚引用

JDK 1.2 版之后引入了软(SoftReference)、弱(WeakReference)、虚(PhantomReference)三种引用。

  • 强引用:最传统的「引用」的定义,是指在程序代码之中普遍存在的引用赋值,即类似Object obj=new Object()这种引用关系。只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。

  • 软引用:描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。

  • 弱引用:描述那些非必须对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。

  • 虚引用:是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。

ThreadLocalMap设计成弱引用

static class ThreadLocalMap {
    static class Entry extends WeakReference<ThreadLocal<?>> {
        /** The value associated with this ThreadLocal. */
        Object value;
        Entry(ThreadLocal<?> k, Object v) {
            super(k);
            value = v;
        }      
}

如果我们的代码中不需要 ThreadLocal 这个对象的话,即 ThreadLocal = null。但是 ThreadLocalMap 是线程的变量,如果线程一直运行,那么 ThreadLocalMap 永远不会为 null。

如果使用强引用,Entry 中的 k 强引用了 ThreadLocal ,ThreadLocal 永远不能释放

如果使用弱引用,ThreadLocal 在垃圾回收时将释放,Entry 中的 k 将变为 null

原文链接:https://blog.csdn.net/xiaohulunb/java/article/details/103837418