采取以下案例
// class Toy {
// public Object b = new Object();
// }
Toy toy = new Toy();
Object theB = toy.b;
toy = null;
// Can toy instance be garbage collected right now?
我认为可能无法对toy
进行垃圾回收,因为theB
目前指的是toy.b
,变量b
无法生效toy
(As { {1}}是b
)的实例成员变量?
答案 0 :(得分:3)
是的,它可以,因为Toy
的实例没有强引用。想一想:你怎么能回顾原来的Toy
实例?不可能,不是吗?因此,它确实是垃圾,并将被收集。
有关Java中可访问性和类型的引用的更多信息(即,强引用,弱引用 em>等,以及这些引用如何与垃圾收集器交互),看看excellent documentation of the package java.lang.ref。
为了进一步扩展讨论,并且绝对准确,我可以想到至少有一种情况,即使在Toy
之后,toy = null
的实例永远无法收集,类Toy
的代码不同。
如果Toy
类的构造函数在某种全局变量中添加对新创建的实例的引用(或者更确切地说,如果可以从GC根目录强烈访问该对象)。例如:
public class Toy {
private static final List<Toy> myToys = new ArrayList<>();
public Toy() { myToyw.add(this); }
}
如果是这种情况,那么当您在代码中执行toy = null
时,实例仍然无法仅仅因为仍然有办法到达它(通过强引用),即Toy.myToys.get(0)
。
但是,这只是为了完整性。 我强烈建议反对此类代码,因为它肯定会带来很多麻烦,包括但不限于奇怪的内存泄漏(即,实例无法进行GCed )和多线程的问题(即,您在构造函数返回之前发布了对实例的引用,然后另一个线程可能会将对象视为部分初始化,即可能处于不一致状态)。
答案 1 :(得分:0)
是的,如果没有人提及toy
,可以对其进行垃圾回收。 b
类型为Object
后,它仅引用自己的Class
对象,而不会引用任何其他内容,因此toy
不会引用b
。