执行" m1 = null后,有多少个对象符合垃圾回收的条件;平方米= NULL;&#34 ;?

时间:2015-10-21 11:54:25

标签: java garbage-collection

执行m1 = null; m2 = null;后,我很难理解。有多少个对象可以进行垃圾收集?

public class MyTest {
    MyTest m;

    void show() {
        System.out.println("Hello this is show method.");
    }

    public static void main(String args[]) {
        MyTest m1 = new MyTest();
        MyTest m2 = new MyTest();
        MyTest m3 = new MyTest();
        m1.m = m2;
        m2.m = m3;
        m3.m = m1;
        m1 = null;
        m2 = null;
        // Question here: How many objects will be eligible for garbage collection?
    }
}

4 个答案:

答案 0 :(得分:80)

零。

对象参考图如下所示:

Circular

您可以看到引用是循环的。从mainm3的引用可使m3对象保持活动状态。反过来,m3保持活跃m1,这会使m2与GC保持一致。

请注意,如果您将m3设置为null,则所有三个对象都将立即符合GC条件,尽管每个对象都存在循环引用。 GC非常聪明,可以确定所有引用都来自符合GC标准的对象,并收集所有三个。

答案 1 :(得分:24)

可能全部3个。 //标记后没有引用任何变量,因此优化器在此时可以将它们从帧中删除。

答案 2 :(得分:21)

瞧! GC 将在此处收集任何内容!让我们看看这里到底发生了什么。当您创建m1m2m3 MyTest的三个对象时,对象的创建方式如下(例如,对象引用ID从410开始):

m1    MyTest  (id=410)
    m    null
m2    MyTest  (id=412)
    m    null
m3    MyTest  (id=414)
    m    null

初始化时

m1.m = m2;
m2.m = m3;
m3.m = m1;

对象现在看起来像:

m1    MyTest  (id=410)
    m    MyTest  (id=412)
m2    MyTest  (id=412)
    m    MyTest  (id=414)
m3    MyTest  (id=414)
    m    MyTest  (id=410)
        m    MyTest  (id=412)
            m    MyTest  (id=414)
                m    MyTest  (id=410)
                    .
                    .
                    . (This is circular)

但是,在您将m1m2重新初始化为null后,对象看起来像:

m1    null
m2    null
m3    MyTest  (id=414)
    m    MyTest  (id=410)
        m    MyTest  (id=412)
            m    MyTest  (id=414)
                m    MyTest  (id=410)
                .
                .
                .

看,m1m2现在是null,但他们的引用仍在m3中存在!

答案 3 :(得分:9)

无,因为通过m3

构建的循环引用仍然可以访问它们