【发布时间】:2014-06-10 15:50:04
【问题描述】:
多年来,我一直毫无疑问地使用final 关键字来表示在实例/类的生命周期内不应更改的字段。我突然想到了这个……
所以给出这个例子:
public class TestFinalGC{
private TestFinalGC(){}
private final Object obj = new Object();
public static void main(String []args){
TestFinalGC instance = new TestFinalGC();
// instance Ref -> actual instance ->? obj ref-> actual obj
System.out.println(instance.obj);
instance = null;
//say GC makes sweep here... what happens?
//lets assume theres more code, obj would obviously be eligible for GC on app exit.
}
}
obj 成员如何不在这里泄漏? final 字段是否会自动为 WeakReferences,这样如果对父级的强引用为空,它们就有资格进行垃圾回收?
The JLS does not seem to note anything special about final
更新:
所以我的这个问题是建立在“可达性”和强/弱引用密切相关的前提下的。有this confusing oracle doc on reachability 让我相信嵌套引用应该始终是“高度可达的”。因此,我在所有对象中都将嵌套对象引用设为空,但我收到的所有 cmets 显然不应该是这种情况。
那么,关于“可达性”,如果父引用不再可达,嵌套对象引用是否不再被视为“可达”?
确实可能这个问题的前提是不正确的,但是这里还是有一些耐人寻味的信息需要巩固。
【问题讨论】:
-
否,但答案仍然有效。
final并没有什么特别之处,使其无法进行垃圾回收。 -
@rpg711 仅当您排除可达性时。当 final 字段本身不再可访问时,它就有资格进行 GC。到那时,它所引用的所有内容都变得不可访问并且可能符合条件(除非,例如,它可以通过另一个引用访问)。
-
当
Root->instance被清除时,包含final 字段的实例不再可访问,因此无论final 字段引用什么也不再可访问,只要没有其他引用它。不可访问与弱引用不同。 -
您可以将对象视为村庄,并将引用视为从一个村庄到另一个村庄的单向道路。如果你只能从 A 村走一条路去 B 村,而且如果没有通往 A 村的路(即 A 无法到达),那么 B 村当然也无法到达。 GC 将因此收集 A 和 B。
标签: java memory-leaks garbage-collection final