有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当实例的成员暴露于外部世界时,可以对其进行垃圾收集

以下面的例子为例

// 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的一个实例成员变量)


共 (2) 个答案

  1. # 1 楼答案

    简短的答案

    是的,它可以,因为没有对^{实例的强引用。想一想:你怎么能回到原来的Toy实例?不可能,不是吗?因此,它确实是垃圾,将被收集

    有关Java中可达性引用类型的更多信息(即什么是强引用弱引用,等等,以及这些类型的引用如何与垃圾收集器交互),请查看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时,仍然无法对实例进行GCed,因为仍然有一种方法可以到达它(通过强引用),即Toy.myToys.get(0)

    然而,这只是为了完整性我强烈建议不要使用这种类型的代码,因为它肯定会带来很多麻烦,包括但不限于:,奇怪的内存泄漏(即,实例无法GCD)和多线程问题(即,您在实例的构造函数返回之前发布了对实例的引用,然后另一个线程可能会将对象视为部分初始化,即,可能处于不一致的状态)

  2. # 2 楼答案

    是的,toy可以被垃圾收集,如果没有人引用它。一旦bObject类型,它只引用自己的Class对象,而不引用其他对象,因此toy不被b引用