举个例子
// 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)?
举个例子
// 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 中的可达性和引用类型的更多信息(即,什么是强引用、弱引用等,以及这些类型的引用如何与垃圾收集器交互),请查看 java.xml包的优秀文档。 lang.ref。
为了扩展讨论,并且绝对准确,我可以想到至少一种情况,即使在您的 , 类的代码不同之后,Toy也永远无法收集实例。toy = nullToy
如果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)和多线程问题(即,您发布了对实例在其构造函数返回之前,那么另一个线程可能会将该对象视为已部分初始化,即可能处于不一致状态)。
是的,toy如果没有人提及它可以被垃圾收集。一旦b是类型Object,它只引用它自己的Class对象,没有别的,所以toy不被. 引用b。