Java 对象垃圾收集

时间:2021-07-09 08:36:28

标签: java garbage-collection

我正在做 OCA Java 认证,但不确定如何理解一个问题的答案。

public class Test {

public static void main(String[] args){
    Student s1 = new Student("o1"); 
    Student s2 = new Student("o2");
    Student s3 = new Student("o3");
    s1=s3; 
    s3=s2;
    s2=null;
    //HERE
    }
}

问题是在 //HERE 点之后哪个对象可用于垃圾回收。

在线测试提供的答案是:一个物体(o1)。

谁能解释一下为什么?

4 个答案:

答案 0 :(得分:6)

考虑一个简单的类学生。

第 1 步:

Student s1 = new Student("s1"); 
Student s2 = new Student("s2");
Student s3 = new Student("s3");

s1, s2, s3 正在引用堆空间中的 3 个对象

enter image description here

第 2 步:

Student s1 = s3; 

s1 现在正在引用堆空间中的 s3 对象

堆空间中的对象s1已经失去了他的引用

enter image description here

第 3 步:

Student s1 = s3;
Student s3 = s2;

变量s1引用s3堆空间

变量s3引用s2堆空间

enter image description here

第 4 步:

Student s1 = s3;
Student s3 = s2;
Student s2 = null;

变量s1引用s3堆空间

变量s3引用s2堆空间

变量 s2 丢失了他的引用(空指针)

enter image description here

结论:

第 11 行之后,一个对象有资格进行垃圾回收

答案 1 :(得分:4)

每次弹出这类问题,答案都是一样的:在注释HERE之后,每个对象都有资格进行垃圾回收。该行之后没有使用任何内容,因此不存在对任何对象的强引用,因此所有内容都可以进行 GC。不幸的是,这类问题只有在为考试获得正确“分数”的情况下才有意义,因此人们按照他们的方式学习它们。现实情况是,如果没有更广泛的可达性背景,它们只会让用户感到困惑,imo。

想一想 - 在该评论之后是否有对您的任何对象的任何实时引用?否。因此,是否每个实例都有资格进行 GC?是的。请注意,它们在该评论之后才有资格,而不是在方法结束之后。不要将范围可达性混在一起。

答案 2 :(得分:1)

Student s1 = new Student("o1"); 
Student s2 = new Student("o2");
Student s3 = new Student("o3");
s1=s3; // The "s1" variable now points to the object referenced to by s3, ie "o3"
s3=s2; // The "s3" variable now points to the object referenced to by s2, ie "o2"
s2=null; // The "s2" variable points to nothing

在执行结束时,对象“o3”和“o2”被变量(分别为“s1”和“s3”)引用。因此,对象“o1”没有被任何变量指向,可以被垃圾收集器销毁。

答案 3 :(得分:1)

退出该方法后,所有对象都将有资格进行垃圾回收,因为 s1、s2、s3 是局部变量,引用不会被传递到外部。

然而在该方法的最后一行,s1 持有对 o3 的引用,s2 不指向任何地方,s3 指向 o2。只有 o1 没有指向他的引用,因此它有资格进行垃圾收集。

相关问题