2014-11-06 56 views
2

我想了解弱引用弱引用和困惑,我看到在維基以下代碼:關於Java的

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變爲零,即使它保持很強的參考(新字符串)?

+0

我所知道的是弱引用不被垃圾收集,而強大的引用避免。既然如此,我不明白爲什麼r變成空而sr不是 – attaboy182 2014-11-06 00:27:28

+1

如果我的理論是正確的,存儲在sr中的字符串存儲在字符串池中,因爲它是使用字符串文字創建的。存儲在r中的字符串不是,因爲它是使用'new'關鍵字創建的。由於字符串「sr」仍然在字符串池中引用,因此它被認爲是強烈引用的(這是純粹的理論;沒有親自挖掘) – 2014-11-06 00:32:03

回答

6

第一個WeakReference變爲空,因爲它是對新String對象的唯一引用,所以沒有強引用,它就有資格收集。

第二個WeakReference不會變爲空,因爲它引用的對象是字符串字面值,Java語言規範需要該字符串字面值來實現,這會導致它從字符串池強引用,從而防止其垃圾採集。

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

沒有強烈的提及這條線。只有WeakReferencer知道這個對象,因此唯一參考new String("I'm here")WeakReferencer而沒有其他人。

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

在聲明String內嵌像這樣在Java中,它給人的聲明類的隱式硬參考字符串文字。這與String interning如何在Java中工作有關,並且也是爲什麼如果您在類的許多不同位置聲明相同的字符串文字,Java將只創建對該字符串文本的單個引用。

參見this answer

+0

第二行不是「在線聲明字符串」。它聲明瞭一個_local variable_,'sr',它被初始化爲指向一個WeakReference對象,它指向一個_literal_ String。字符串不會被GC回收,因爲像所有文字字符串一樣,它具有來自庫的實字符串表的強引用。我不喜歡挑剔,但不精確的語言是造成這些新手無能的主要原因。 – 2014-11-06 01:45:53

+0

我特指的是String如何被聲明,即。作爲文字,而不是整條線路本身在做什麼。我可能錯誤地認爲'sr'是一個局部變量的事實已經被理解了。 – 2014-11-06 01:55:15