本文介绍了WeakReference字符串没有垃圾收集?怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在维基百科阅读 WeakReference ,我看到了这段代码

I'm reading about WeakReference in wikipedia and I saw this code

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 = null,静态=我在这里

after gc: r=null, static=I'm here

sr r 变量都是引用字符串对象。 r 现在是垃圾收集但为什么 sr 在调用垃圾收集器后没有收集垃圾?

sr and r variable are both referring string objects. r is now garbage collected but, why sr didn't garbage collected after calling garbage collector?

我只是好奇这是怎么发生的。

I'm just curious how this happened.

推荐答案

NOT 因为字符串池本身

真正的原因是 ReferenceTest class有一个String对象的隐式硬引用,表示我在这里 literal。该硬引用意味着 sr 中的弱引用不会被垃圾收集破坏。

The real reason is that the ReferenceTest class has an implicit hard reference to the String object that represents the "I'm here"literal. That hard reference means that the weak reference in sr won't be broken by the garbage collection.

实际上:


  • 隐式参考是必要的,即使没有与文字对应的String对象也是池化的。 (他们 汇集...... JLS有效地需要这个...但我说即使它们不是,也需要引用。替代方案将是Java每次评估一个字符串文字表达式时都要编写一个新的String对象。这将是可怕的效率低下!!)

  • The implicit reference would be necessary, even if String objects corresponding to literals weren't pooled. (They are pooled ... the JLS effectively requires this ... but I'm saying the references would required even if they weren't. The alternative would be for Java to mint a fresh String object each time a string literal expression was evaluated. That would be horribly inefficient!!)

字符串池内部使用弱引用形式...以便可以对未引用的实习字符串进行垃圾回收。如果不是这样,那么每个新的实习字符串都会出现内存泄漏。

The string pool internally uses a form of weak reference ... so that unreferenced interned strings can be garbage collected. If that weren't the case, then every new interned string would be a memory leak.

无论如何......如果你小心地构造一个字符串而不使用字符串文字并实习它,如下所示:

Anyway ... if you carefully construct a string without using a string literal and intern it, like this:

    char[] chars = {'a', 'b', 'c'};
    WeakReference r = new WeakReference(new String(chars).intern());

...您应该发现弱引用(最终)被破坏。 (虽然可能需要几个GC循环。)

... you should find that the weak reference is (eventually) broken. (It might take a couple of GC cycles though.)

这篇关于WeakReference字符串没有垃圾收集?怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 06:51