views:

105

answers:

7

Suppose I have a doubly linked list. I create it as such:

MyList list = new MyList();

Then I add some nodes, use it and afterwards decide to throw away the old list like this:

list = new MyList();

Since I just created a new list, the nodes inside the old memory area are still pointing to each other. Does that mean the region with the old nodes won't get garbage collected? Do I need to make each node point to null so they're GC'd?

+7  A: 

No, you don't. The Java GC handles cyclic references just fine.

Conceptually, each time the GC runs, it looks at all the "live" root references in the system:

  • Local variables in every stack frame
  • "this" references in every instance method stack frame
  • Effectively, all static variables (In fact these are really referenced by Class objects, which are in turn referenced by ClassLoaders, but lets ignore that for the moment.)

With those "known live" objects, it examines the fields within them, adding to the list. It recurses down into those referenced objects, and so on, until it's found every live object in the system. It then garbage collects everything that it hasn't deemed to be live.

Your cyclically referenced nodes refer to each other, but no live object refers to them, so they're eligible for garbage collection.

Note that this is a grossly simplified summary of how a garbage collector conceptually works. In reality they're hugely complicated, with generations, compaction, concurrency issues and the like.

Jon Skeet
A: 

The garbage collector looks for objects that isn't referenced anywhere. So if you create a object and you loose the reference like the example the garbage collector will collect this.

Daniel Moura
A: 

No -- Java (at least as normally implemented) doesn't use reference counting, it uses a real garbage collector. That means (in essence) when it runs out of memory, it looks at the pointers on the stack, in registers, and other places that are always accessible, and "chases" them to find everything that's accessible from them.

Pointers within other data structures like your doubly-linked list simply don't matter unless there's some outside pointer (that is accessible) that leads to them.

Jerry Coffin
A: 

No, the GC will reclaim them anyways so you don't need to point them to null. Here's a good one paragraph description from this JavaWorld article:

Any garbage collection algorithm must do two basic things. First, it must detect garbage objects. Second, it must reclaim the heap space used by the garbage objects and make it available to the program. Garbage detection is ordinarily accomplished by defining a set of roots and determining reachability from the roots. An object is reachable if there is some path of references from the roots by which the executing program can access the object. The roots are always accessible to the program. Any objects that are reachable from the roots are considered live. Objects that are not reachable are considered garbage, because they can no longer affect the future course of program execution.

Taylor Leese
A: 

The garbage collector looks if objects are referenced by live threads. If objects are not reachable by any live threads, they are eligible for garbage collection.

It doesn't matter if the objects are referencing each other.

Jesper
A: 

As others have pointed out, the Java garbage collector doesn't simply look at reference counting; instead it essentially looks at a graph where the nodes are the objects that currently exist and links are a reference from one object to another. It starts from a node that is known to be live (the main method, for instance) and then garbage collects anything that can't be reached.

The Wikipedia article on garbage collection discusses a variety of ways that this can be done, although I don't know exactly which method is used by any of the JVM implementations.

Scott
A: 

If you created your own double linked list, and you put in this double linked list Containers (that contain items from your list); only those containers are linked one to another.

So in your list you'll have an object A contained in A'. A' is linked to B' and B' is a container that hold B etc. And none of the object have to reference another.

In a normal case those containers won't be available from outside (only the content is interesting); so only your list will have references to your containers (remember that your content isn't aware of his container).

If you remove your last reference to your list (the list, not the container nor the content) the GC will try to collect your list content, witch is your containers and your contents.

Since your containers are not available outside the only reference they have is one each other and the main list. All of that is called an island of isolation. Concerning the content, if they still have references in your application, they will survive the GC, if not they won't.

So when you remove your list only A' and B' will be deleted because even if they still have references, those references are part of an island. If A and B have no more references they will be deleted too.

Colin Hebert