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;
}
}
Run Code Online (Sandbox Code Playgroud)
执行此代码后存在多少个对象引用?为什么?
尽管存在配方问题,但该片段在垃圾收集的某些方面实际上非常有启发性.让我们逐行看一下.
Point point_1 = new Point(5,5);
Run Code Online (Sandbox Code Playgroud)
所以我们已经声明了一个引用变量point_1,它指向一个new Point.我们现在假设构造函数Point没有做任何奇特的事情,只是final int x, y用给定的值设置字段.
因此,我们现在有这样的事情:
现在让我们来看看下一行:
Point point_2 = new Point(7,8);
Run Code Online (Sandbox Code Playgroud)
现在我们有这样的事情:
现在让我们来看看下一行:
Circle circle_1 = new Circle(point_2, 10);
Run Code Online (Sandbox Code Playgroud)
这里我们还不太清楚如何Circle实现,但是假设它有一个final Point center和final int radius字段是合理的,Point center具体来说,它只是设置对给定的引用Point(即没有防御性复制,因为它Point是不可变的).
所以现在我们可能有这样的事情:
然后使用接下来的两个语句,我们分别设置point_1和point_2指向null:
point_1 = null;
point_2 = null;
Run Code Online (Sandbox Code Playgroud)
所以现在我们有这样的事情:
我们现在可以观察到:
[aPoint(5 5)]不再可访问[aPoint(7 8)]虽然不再被提及,但point_2仍然被提及[aCircle(10)].center.垃圾收集性是通过实时引用是否可以访问对象来定义的.对象[aPoint(5 5)],我们可以强烈假设(基于我们如何思考Point实施),不再可达,所以它是符合回收(这是一个垃圾!没有人能"捡起来"吧!).
另一方面,对象[aPoint(7, 8)]仍然被引用[aCircle(10)].center,所以我们可以说它不适合收集(它不是垃圾!有人还在"挂"它!).
因此,没有,绝对设定一个参考null确实不使对象以前被称为收集自动有资格.它取决于对象本身,是否有对该对象的引用.
当然,设置对null CAN的引用有助于使对象有资格进行收集,例如,当该引用是对象的最后剩余时.
你不但是,必须始终设置参照null,使垃圾收集"作品".当变量超出范围时,引用不再存在,因此在明确设置的那些情况下,null只是冗余代码.
显式设置为null DOES工作的典型示例是Stack示例:当从顶部元素弹出时Stack,Stack不应再从其内部数据结构引用该对象.
答案是:
Point和Circle类的详细信息,就不可能知道甚至创建了多少个对象引用.main方法退出后,没有任何对象可以到达......引用是否仍然"存在".我们可以推断,在main方法返回之前的那个时间点,将有一个Circle对象的可达引用和一个可达的引用Point.但是必须对这两个类如何实现以进行推断做出一些(合理的)假设.(例如,必须假设各个构造函数不添加Point和Circle引用某些静态数据结构.)
当引用它们时,对象是否被清除?
否.垃圾收集器运行时清除对象,并确定无法再访问相关对象.从这个意义上说,"可达"意味着你可以通过跟随对象的一系列引用来到达对象,从以下开始:
(我已经简化了GC和可达性的解释,以避免将OP与他/她还不会理解的东西混淆.)
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |