2009-01-17 30 views
75

由於只用在程序設置一個假想的實用工具類:靜態字段是否爲垃圾收集打開?

class MyUtils { 
    private static MyObject myObject = new MyObject(); 
    /*package*/static boolean doStuff(Params... params) { 
     // do stuff with myObject and params... 
    } 
} 

將不再被使用時myObject的收集垃圾,還是會堅持圍繞該計劃的生活嗎?

回答

93

加載類時,無法爲垃圾收集選擇靜態變量。當相應的類加載器(負責加載這個類)本身被收集用於垃圾時,可以收集它們。

檢查出JLS Section 12.7 Unloading of Classes and Interfaces

當且僅當其定義類裝載程序 可以由垃圾 收集器回收[...]通過裝載類和接口 類或接口可以被卸載 引導程序加載程序可能不會被卸載。

+0

鏈接已損壞。 – starblue 2009-01-17 11:00:58

+0

@bruno,根據你的鏈接,這是否意味着類加載器持有對它加載的每個類的引用,即使加載的類沒有靜態成員? – Pacerier 2014-08-23 07:07:48

6

我認爲this回答你的問題 - 基本上沒有,除非這個類來自一個特殊的類加載器,並且卸載這個類。

+2

或者直到有人更新靜態字段。 – 2012-11-05 16:41:43

+0

確實 - 它沒有標記爲final – Tom 2012-11-05 21:16:16

42

靜態變量由ClassLoaders引用的Class對象引用-so除非ClassLoader以某種方式丟棄該類(如果這甚至可能)或者ClassLoader本身有資格收集(更可能 - 考慮卸載webapps)靜態變量(或更確切地說,它們引用的對象)將不會被收集。

+1

不包含靜態變量的Class對象是否被其類加載器引用? – Pacerier 2014-08-23 05:35:15

13

如果要將臨時對象用於靜態初始化然後進行處理,可以使用靜態初始化塊,例如,

class MyUtils { 
    static 
    { 
     MyObject myObject = new MyObject(); 
     doStuff(myObject, params); 
    } 

    static boolean doStuff(MyObject myObject, Params... params) { 
     // do stuff with myObject and params... 
    } 
} 

由於靜態初始化劑塊是一種特殊的靜態方法,myObject的是局部變量並且可以是垃圾收集的塊執行完畢後。

8

myObject是參考而不是對象。 當沒有引用指向它時因爲無法訪問而自動垃圾收集對象。

所以還落後的靜態引用「myObject的」對象可以被收集,如果你取消對它的引用垃圾與

myObject = null; 

而且有這個對象沒有其他引用。

但是,靜態引用和變量在您的程序的整個生命週期中保持不變。