关于java中弱引用的困惑

时间:2014-11-06 00:22:52

标签: java reference weak-references

我试图理解弱引用,我在wiki中看到了以下代码:

import java.lang.ref.WeakReference;

public class ReferenceTest {
    public static void main(String[] args) throws InterruptedException {

            WeakReference r = new WeakReference(new String("I'm here"));
            WeakReference sr = new WeakReference("I'm here");
            System.out.println("before gc: r=" + r.get() + ", static=" + sr.get());
            System.gc();
            Thread.sleep(100);

            // only r.get() becomes null
            System.out.println("after gc: r=" + r.get() + ", static=" + sr.get());

    }
}

有人可以告诉我为什么只有r变为null,即使它持有强引用(新字符串)?

2 个答案:

答案 0 :(得分:6)

第一个WeakReference变为null,因为它是对新String对象的唯一引用,因此没有对它的强引用,并且它有资格进行收集。

第二个WeakReference不会变为null,因为它引用的对象是一个字符串文字,这是Java语言规范要求实现的,这会导致它从字符串池强引用,这会阻止它的垃圾回收

答案 1 :(得分:3)

WeakReference r = new WeakReference(new String("I'm here"));

没有强烈的参考这条线。只有WeakReference r知道此对象,因此对new String("I'm here")的唯一引用是WeakReference r而不是其他人。

WeakReference sr = new WeakReference("I'm here");

当您在Java中声明这样的String内联时,它会为声明类提供对String文本的隐式硬引用。这与String interning在Java中的工作方式有关,也是为什么如果在类的许多不同位置声明相同的String文字,Java将只创建对该字符串文字的单个引用。

另见this answer