我在阅读“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