Java 当对对象的引用为空时,对象是否已清理?

Java 当对对象的引用为空时,对象是否已清理?,java,Java,执行此代码后存在多少对象引用?为什么?执行此代码后,完全没有,因为它将退出:-) 如果您的意思是在退出前的某个点,堆栈上有一个指向您的圆的引用,而圆中有一个指向第二个点的引用,假设构造函数存储了它。答案是: 定义对象引用“存在”的含义 如果没有点和圆类的详细信息,甚至不可能知道创建了多少个对象引用 答案是不相关的,因为在main方法退出后,将无法访问任何对象。。。参考文献是否仍然“存在” 我们可以推断,在main方法返回之前的时间点,将有一个对圆对象的可到达引用和一个对点的可到达引用。但我们必须

执行此代码后存在多少对象引用?为什么?

执行此代码后,完全没有,因为它将退出:-)

如果您的意思是在退出前的某个点,堆栈上有一个指向您的圆的引用,而圆中有一个指向第二个点的引用,假设构造函数存储了它。

答案是:

  • 定义对象引用“存在”的含义
  • 如果没有
    类的详细信息,甚至不可能知道创建了多少个对象引用
  • 答案是不相关的,因为在
    main
    方法退出后,将无法访问任何对象。。。参考文献是否仍然“存在”
  • 我们可以推断,在
    main
    方法返回之前的时间点,将有一个对
    对象的可到达引用和一个对
    的可到达引用。但我们必须对这两个类是如何实现的做出一些(合理的)假设,才能做出这样的推断。(例如,必须假设相应的构造函数没有将
    引用添加到某个静态数据结构。)

    当对对象的引用为空时,对象是否已清理

    不会。当垃圾回收器运行时,对象会被清理,并且它会确定问题对象不再可访问。从这个意义上说,“可到达”意味着您可以通过从以下位置开始的对象引用链来访问该对象:

    • 某个类的静态属性
    • 某个线程当前正在执行的某个方法的局部变量
    • 某个其他可到达对象的属性,或
    • 其他可到达数组的元素

    (我简化了GC和可达性的解释,以避免将OP与他/她还不理解的东西混淆。)

    尽管存在公式问题,但该片段实际上对垃圾回收的某些方面很有指导意义。让我们一行一行地看一下。

    public class App1 
    {
    
     public static void main(String[] args) 
     {
       Point point_1 = new Point(5,5);
       Point point_2 = new Point(7,8);
       Circle circle_1 = new Circle(point_2, 10);
       point_1 = null;
       point_2 = null;
     }
    }
    
    所以我们声明了一个参考变量
    point_1
    ,它指向一个
    新点。现在让我们假设
    的构造函数没有做任何花哨的事情,只是用给定的值设置字段
    final int x,y

    因此,我们现在有这样的东西:

    现在我们来看看下一行:

     Point point_1 = new Point(5,5);
    
    Point point_2 = new Point(7,8);
    
    现在我们有了这样的东西:

    现在我们来看看下一行:

     Point point_1 = new Point(5,5);
    
    Point point_2 = new Point(7,8);
    
    在这里,我们也不太清楚圆是如何实现的,但可以合理地假设它有一个
    终点中心
    最终整数半径
    字段,特别是
    点中心
    ,它只是将参考设置为给定的
    (即,由于
    是不可变的,因此没有防御性复制)

    现在我们可能会有这样的情况:

    然后,在接下来的两条语句中,我们分别将
    point_1
    point_2
    设置为指向
    null

    Circle circle_1 = new Circle(point_2, 10);
    
    现在我们有了这样的东西:

    我们现在可以看到:

    • 无法再访问对象
      [aPoint(5)]
    • 对象
      [aPoint(7 8)]
      虽然不再由
      点2
      引用,但仍然由
      [aCircle(10)]引用。中心
    垃圾回收性是由一个对象是否可以通过一个活动引用访问来定义的。我们可以强烈地假设(根据我们认为的
    的实现方式)该对象不再是可访问的,因此它有资格被回收(它是一个垃圾!现在没有人可以“捡起它!)

    另一方面,对象
    [aPoint(7,8)]
    仍然由
    [aCircle(10)]引用。中心
    ,因此我们可以说它不符合收集条件(它不是垃圾!有人仍然“抓住”它!)


    道德的 因此,不,明确地说,将引用设置为
    null
    不会使以前被引用的对象自动符合收集条件。这取决于对象本身,无论是否存在对该对象的引用

    当然,将引用设置为
    null
    有助于使对象符合收集条件,例如,当该引用是对象的最后一个剩余引用时

    但是,您不必总是将引用设置为
    null
    以使垃圾收集“工作”。当变量超出范围时,引用不再有效,因此在这种情况下,显式设置为
    null
    只是冗余代码

    显式设置为
    null
    有效的经典示例是
    堆栈
    示例:当从
    堆栈
    弹出顶部元素时,
    堆栈
    不应再从其内部数据结构引用对象

    另见
    • 有效Java第二版,第6项:消除过时的对象引用
    相关问题

    @paxdiablo:yuml.me;另请看,哇,你的答案越来越酷,继续吧!你很快就会让Jon Skeet为他的钱跑一趟。:PMinor point:编译器可能不会费心在堆栈上放圆圈1,因为它是一个未使用的本地。。。。。