采取以下情况
// 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
生存(因为b
是toy
的实例成员变量)? 最佳答案
简短的答案
是的,可以,因为没有对Toy
实例的强引用。想一想:您怎么能回头回到原始的Toy
实例?不可能,不是吗?因此,它确实是垃圾,将被收集。
有关Java的可访问性和引用类型的更多信息(即强引用,弱引用等,以及这些类型的引用如何与Garbage Collector交互),请查看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
时,仍然不能仅仅通过实例化GC实例,因为仍然有一种方法(通过强引用)到达它,即Toy.myToys.get(0)
。但是,这只是为了完整性。 我强烈建议不要使用这种类型的代码,因为它肯定会带来很多麻烦,包括但不限于奇怪的内存泄漏(即,实例不能被GC)和多线程问题(即,您发布了参考)实例返回其构造函数之前返回到实例,然后另一个线程可能会将该对象视为部分初始化的对象(即可能处于不一致状态)。
关于java - 当实例的成员暴露于外界时是否可以对其进行垃圾回收,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15403052/