4

当我在 wikipedia http://en.wikipedia.org/wiki/Weak_reference上阅读以下示例代码时

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());

            }
    } 

gc 之前的输出 :r=我在这里,static=我在这里 gc 之后:r=null,static=我在这里

我无法理解 gc 之后的输出,sr(WeakReference) 对字符串池中字符串的强引用在哪里

4

3 回答 3

0

sr 不会被垃圾回收,因为 String 在内部缓存了字符串。因此内部缓存仍然有一个引用,因此 WeakRefence 不会被垃圾收集。

在 sr 的情况下,静态构造的 String 被添加到缓存中。使用 new Stirng("...") 构造的字符串对象不是。因此,通常最好不要使用 new String("...")。

于 2013-07-05T09:48:48.607 回答
0

在第一种情况下,当您使用创建字符串new String("I'm here")对象时,总是在堆上创建对象。因此,如果您调用System.gc();,那么该对象可以直接用于垃圾收集。

而在第二种情况下,您将字符串作为对象的引用传递。所以这里它不会创建字符串的新对象,因为字符串直接初始化为对象的引用。所以它不能用于垃圾收集。因为这个字符串将被保留在string-pool.

于 2013-07-05T09:55:07.420 回答
0

字符串池中的对象不会被垃圾收集,因为它们不驻留在堆中。如果你想new String()在池中放置一个,你可以选择使用String#intern()

于 2013-07-05T09:55:35.607 回答