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,因为它是一个未使用的本地。。。。。