我有一个关于Java GC的简单问题。一些例子:
Object instance = new Object();
longMethod(instance);
...
// First example
private void longMethod(Object arg) {
Thread.sleep(1000 * 60 * 60)
// this method works 1hr. Does it keep reference to Object and GC canot release it?
}
//Seconde example
private void longMethod(Object arg) {
arg = null;
Thread.sleep(1000 * 60 * 60)
// we clear reference in method. Can GC relese Object now?
}
那么"实例"的生命周期是什么?在这两种情况下?感谢。
答案 0 :(得分:5)
在这两种情况下,Object instance
(调用longMethod
的方法的局部变量)保存对实例的引用,因此GC无法在调用的方法之前释放它longMethod
结束。
请注意,arg = null
仅将longMethod
内的本地引用设置为null。它不会更改调用instance
的方法中longMethod
变量的值。
答案 1 :(得分:2)
Java 按值传递 :将第二种方法中的局部变量arg
设置为null并不意味着调用者中的局部变量方法也设置为引用null。因此,调用者中的对象仍然有一个指向它的引用。
考虑在方法中创建新对象的情况:
private void longMethod(Object arg) {
arg = new Object(); // Line 1
Thread.sleep(1000 * 60 * 60);
arg = null; // now the object created in line 1 is eligible for GC
}
在这种情况下,使用arg = new Object();
创建的对象(与调用方法中创建的对象不同)对于GC符合条件。
考虑一下你在调用者方法中有这个的情况:
Object instance = new Object(); // Line 1
longMethod(instance);
instance = null; // now the object created in line 1 is eligible for GC (see note below)
现在,先前在第1行中创建的对象也符合GC 的条件,假设没有对longMethod
中创建的对象的引用。