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

How many objects will be eligible for garbage collection after executing "m1=null; m2=null;"?

执行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?
    }
}

None 因为它们仍然可以通过您通过 m3

在那里构建的循环引用访问

零。

对象参考图如下所示:

可以看到引用是循环的。从 mainm3 的引用使 m3 对象保持活动状态。反过来,m3 保持活动状态 m1,从而使 m2 免于 GC。

请注意,如果将 m3 设置为 null,则所有三个对象都将立即符合 GC 条件,尽管它们中的每一个都存在循环引用。 GC 足够聪明,可以找出所有引用都来自符合 GC 条件的对象,并收集所有三个。

瞧! 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 个。 // 标记后没有引用任何变量,因此优化器此时有权将它们从框架中删除。