This is a rather common case: class Team contains a list of all its Member instances while a Member refers to its Team. The Java code looks something like this:
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();
}
}
Consider also a function test
which creates a Team
instance and terminates.
public static void test() {
Team team = new Team("Family",
"William", "Kate", "George");
System.out.print(team);
}
According to common sense, after function test terminates, the team
object and all its Member
instances should be released. However the reference count of team
is non-zero, since all Member
-s refer to it, while each Member
cannot be released, because team
is holding it.
Some languages provide so called "weak references" (not increasing reference count, but set to null automatically when referred object is released) to cope with this problem, but Java doesn't have anything like that.
I can imagine a GC engine that identifies a "closed" group of objects which refer to each other, but have no external references, and such a group can be released. But is JVM is guaranteed to be that smart? I haven't found any Java document to discuss this issue, so every time I have to create this sort of a structure I am worried. I am especially interested in Dalvik VM.