有多少对象符合垃圾收集条件?

Lea*_*ner 6 java garbage-collection

1.  public class Tahiti {
2.      Tahiti t;
3.      public static void main(String[] args) {
4.          Tahiti t = new Tahiti();
5.          Tahiti t2 = t.go(t);
6.          t2 = null;
7.          // more code here
8.      }
9.      Tahiti go(Tahiti t) {
10.         Tahiti t1 = new Tahiti(); Tahiti t2 = new Tahiti();
11.         t1.t = t2; t2.t = t1; t.t = t2;
12.         return t1;
13.     }
14. }
Run Code Online (Sandbox Code Playgroud)

到达第7行时,有多少对象符合垃圾回收的条件?

根据这个问题给出的答案,第11行没有符合GC资格的对象; 但据我说,至少有一个对象,t2,在第6行设置为null,应该有资格进行垃圾收集.

Eel*_*lke 7

第6行的变量t2不是对象的唯一引用.从t到对象t2的引用是在函数go中创建的,而对象t2又保持对t1的引用,t1是函数go返回的相同对象.因此,第6行仅减少了引用的数量,但仍然存在对该对象的实时引用.

编辑:让我们尝试更详细的解释,首先我重新编写代码,使解释更容易.每行一个语句和较少混淆的变量名称+我用字母A,B和C标识了三个相关对象.

1.  public class Tahiti {
2.      Tahiti u;
3.      public static void main(String[] args) {
4.          Tahiti t = new Tahiti(); // object A
5.          Tahiti t2 = t.go(t);
6.          t2 = null;
7.          // more code here
8.      }
9.      Tahiti go(Tahiti s) {
10.         Tahiti s1 = new Tahiti(); // object B
11.         Tahiti s2 = new Tahiti(); // object C
12.         s1.u = s2;
13.         s2.u = s1;
14.         s.u = s2;
15.         return s1;
16.     }
17. }
Run Code Online (Sandbox Code Playgroud)

在第4行:变量t被初始化以引用新对象.让我们称这个对象本身为A(它通常在java中没有名称,但为了这个解释,它会更容易).

在第5行:t传递给函数go,所以我们转到第9行

在第9行:参数s引用在第4行创建的对象A.

第10行:初始化变量s1以指向对象B.

第11行:初始化变量s2以引用对象C.

第12行:s1.u设置为引用s2,这意味着对象B获得对C的引用

第13行:s2.u设置为引用s1,因此对象C得到对B的引用

第14行:su设置为引用s2,这意味着对象A获得对C的引用,注意C也引用了B,所以此时有一个从A到B的链

第15行返回对象B并返回第5行

第5行:t2设置为参考对象B(B现在直接被t2引用两次,一次因为t指的是引用C的对象A,指的是B)

第6行:引用t2设置为null,因此B丢失一个引用但是t仍然是活的,指向A指的是C指的是B