采取以下情况

// 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生存(因为btoy的实例成员变量)?

最佳答案

简短的答案

是的,可以,因为没有对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/

10-11 05:01