执行"m1 = null; m2 = null;"后,有多少个对象符合垃圾回收的条件?

66 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?
    }
}
Run Code Online (Sandbox Code Playgroud)

das*_*ght 80

零.

对象参考图如下所示:

圆

您可以看到引用是循环的.从参考main,以m3保持m3对象活着.反过来,m3保持活着m1,这m2与GC 保持一致.

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

  • 你是怎么画那么快的?+1 (7认同)
  • @Codebender避免问题足够聪明;-) (2认同)
  • @Codebender实际上它必须在某种程度上找出循环引用,因为它遍历(可能)整个对象图,并且当它到达循环时它的算法不会崩溃. (2认同)

Jos*_*hua 24

可能全部3个.在//标记之后没有引用变量,因此优化器在此权限范围内将它们从帧中删除.

  • 我认为OP的关注点在其他地方!但无论如何你是对的!+1 (4认同)

rak*_*rul 21

瞧!GC将在这里收集任何东西!让我们看看这里到底发生了什么.当你创建的三个对象m1,m2m3MyTest,对象是像下面创建(说的对象引用ID从410开始):

m1    MyTest  (id=410)
    m    null
m2    MyTest  (id=412)
    m    null
m3    MyTest  (id=414)
    m    null
Run Code Online (Sandbox Code Playgroud)

初始化时

m1.m = m2;
m2.m = m3;
m3.m = m1;
Run Code Online (Sandbox Code Playgroud)

对象现在看起来像:

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)
Run Code Online (Sandbox Code Playgroud)

但你重新初始化之后m1,并m2null,对象是这样的:

m1    null
m2    null
m3    MyTest  (id=414)
    m    MyTest  (id=410)
        m    MyTest  (id=412)
            m    MyTest  (id=414)
                m    MyTest  (id=410)
                .
                .
                .
Run Code Online (Sandbox Code Playgroud)

瞧,m1m2null现在,但它们的引用仍然在活着m3!


Aro*_*_dc 9

没有,因为它们仍然可以通过您构建的循环引用到达 m3