我在閱讀「CLR via C#」,看起來在本例中,最初分配給'obj'的對象在執行第1行之後將有資格進行垃圾收集,而不是第2行。Java與.Net中的對象生命週期
void Foo()
{
Object obj = new Object();
obj = null;
}
這是因爲局部變量使用壽命不是由定義的範圍定義的,而是由您上次讀取的。
所以我的問題是:Java呢?我編寫了這個程序來檢查這種行爲,並且它看起來像對象仍然活着。我不認爲JVM在解釋字節碼時可能會限制變量的生命週期,所以我試圖用'java -Xcomp'運行程序來強制編譯方法,但'finalize'不會被調用。看起來對於Java來說這不是真的,但我希望我能在這裏得到更準確的答案。另外,Android的Dalvik VM呢?
class TestProgram {
public static void main(String[] args) {
TestProgram ref = new TestProgram();
System.gc();
}
@Override
protected void finalize() {
System.out.println("finalized");
}
}
補充: 傑弗裏裏希特給出了代碼示例在 「通過C#CLR」,這樣的事情:
public static void Main (string[] args)
{
var timer = new Timer(TimerCallback, null, 0, 1000); // call every second
Console.ReadLine();
}
public static void TimerCallback(Object o)
{
Console.WriteLine("Callback!");
GC.Collect();
}
TimerCallback對MS的.Net只調用一次,如果項目的目標是 '釋放'(定時器在調用GC.Collect()後銷燬),並且如果目標是'Debug'(變量壽命增加,因爲程序員可以嘗試使用調試器訪問對象),則每秒調用一次。但是,無論您如何編譯它,每秒都會調用Mono回調函數。看起來Mono的'Timer'實現存儲對線程池某處實例的引用。 MS實施不這樣做。
我以前在Java規範中找不到這個。請注意,.NET可能比你期望的更瘋狂 - 當實例方法正在執行時,可能收集實例*如果CLR知道將不會引用更多實例變量。 – 2012-01-11 17:15:02