1

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.

cyanide
  • 3,885
  • 3
  • 25
  • 33

1 Answers1

1

Garbage collection in Java works not by counting references, but by starting at the objects that are directly accessible: on the stack, in static fields, and permanently accessible objects such as classes; it then finds every object referenced by those objects, and so on, and marks all objects that no chain of references could access as garbage. Therefore, it will always release cyclically referential garbage, with no need to use a WeakReference.

Vitruvie
  • 2,327
  • 18
  • 25