这是一个相当常见的情况:类成员包含其所有成员实例的列表,而成员引用其团队。 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特别感兴趣。
答案 0 :(得分:1)
Java中的垃圾收集不是通过计算引用,而是通过从可直接访问的对象开始:在堆栈上,在静态字段中,以及永久可访问的对象(如类);然后它会找到这些对象引用的每个对象,依此类推,并标记所有没有引用链可以作为垃圾访问的对象。因此,它将始终释放循环引用垃圾,而无需使用WeakReference
。