2012-10-29 27 views
7

我創建一個示例演示程序讓我說,我怎麼能解除分配靜態變量的引用,在Java方法使用垃圾收集明白了嗎?垃圾收集器在java中的靜態變量或方法上工作嗎?

我使用弱引用未能阻止垃圾收集器。

Sample

public class Sample { 

    private static String userName; 
    private static String password; 
    static { 
     userName = "GAURAV"; 
     password = "password"; 
    } 
    public static String getUserName(){ 
     return userName; 
    } 
    public static String getPassword(){ 
     return password; 
    } 
} 

User

import java.lang.ref.WeakReference; 

public class User { 

    public static void main(String[] args) { 
     /** 
     * Created one object of Sample class 
     */ 
     Sample obj1 = new Sample(); 
     /** 
     * I can also access the value of userName through it's class name 
     */ 
     System.out.println(obj1.getUserName()); //GAURAV 
     WeakReference<Sample> wr = new WeakReference<Sample>(obj1); 
     System.out.println(wr.get()); //[email protected] 
     obj1 = null; 
     System.gc(); 
     System.out.println(wr.get()); // null 
     /** 
     * I have deallocate the Sample object . No more object referencing the Sample oblect class but I am getting the value of static variable. 
     */ 
     System.out.println(Sample.getUserName()); // GAURAV 
    } 

} 
+0

垃圾收集器收集的對象,而不是變量。變量是包含/引用的容器。最重要的是,在大多數情況下,你不想亂搞垃圾收集。 – ignis

+0

靜態過多。你爲什麼要混合它們? –

+0

不,你必須自己清理 – Nactus

回答

16

靜態字段與類,而不是一個單獨的實例相關聯。

靜態字段被清理時保持卸載類的類加載器。在很多簡單的程序中,這絕不是。

如果您希望字段與實例關聯並清理乾淨,那麼實例將被清理,使它們成爲實例字段,而不是靜態字段。

+0

另外,不是字符串字面永遠不會GC'd,因爲它們保存在字符串文字池中?或者這也是在每個類加載器的基礎上? –

+1

AFAIK字符串文字被清理。如果你實習生()很多隨機字符串並丟棄它們,你將無法獲得OOME。在interned字符串是一個問題的地方,直到Java 6它們在PermGen中,並且當你有足夠的堆時,可以獲得OOME填充這個空間。在Java 7中,字符串文字在堆中。 –

+0

感謝您的答案。 –

3

你應該明白,System.gc();不會調用垃圾收集器。它只是禮貌地要求GC刪除一些垃圾。 GC決定要做什麼以及什麼時候開始。因此,在撥打System.gc();,將null分配給變量等時,不要期望您會看到任何即時效果。

GC刪除所有無法以任何方式訪問的對象。因此,如果代碼退出塊定義變量的地方可以刪除對象。分配null將刪除引用。弱引用不會阻止GC刪除對象。

我希望這有助於解釋。

4

比其他節目,回答你的問題

  1. 號的方法是不是垃圾回收,因爲他們不堆中擺在首位存在。

  2. 靜態變量屬於類實例,並且不會被垃圾收集加載一次(對於大多數的一般類加載器)