在Java中发布自阻塞引用

时间:2015-03-08 23:38:08

标签: java garbage-collection jvm

这是一个相当常见的情况:类成员包含其所有成员实例的列表,而成员引用其团队。 Java代码看起来像这样:

public class Team {
    private String name;
    private List<Member> members;

    public Team(final String name, final String... memberNames) {
        this.name = name;

        members = new LinkedList<>();
        for (String memberName : memberNames) 
            members.add(new Member(memberName, this));
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name + ": " + members;
    }

}

class Member {
    private String name;
    private Team team;

    public Member(final String name, Team team) {
        this.name = name;
        this.team = team;
    }

    @Override
    public String toString() {
        return name + " of " + team.getName();
    }

}

还要考虑一个函数test,它创建一个Team实例并终止。

public static void test() {
    Team team = new Team("Family", 
        "William",  "Kate", "George");

    System.out.print(team);
}

根据常识,在函数测试终止后,应释放team对象及其所有Member实例。但是,team的引用计数不为零,因为所有Member - s都引用它,而每个Member都无法释放,因为team持有它。 / p>

有些语言提供了所谓的弱引用&#34; (不增加引用计数,但在引用引用对象时自动设置为null)来解决这个问题,但是Java并没有这样的事情。

我可以想象一个GC引擎可以识别出一个关闭的&#34;相互引用但没有外部引用的对象组,可以释放这样的组。但JVM是否能保证这么聪明?我还没有找到任何Java文档来讨论这个问题,所以每次我必须创建这种结构时我都很担心。我对Dalvik VM特别感兴趣。

1 个答案:

答案 0 :(得分:1)

Java中的垃圾收集不是通过计算引用,而是通过从可直接访问的对象开始:在堆栈上,在静态字段中,以及永久可访问的对象(如类);然后它会找到这些对象引用的每个对象,依此类推,并标记所有没有引用链可以作为垃圾访问的对象。因此,它将始终释放循环引用垃圾,而无需使用WeakReference