1

A <-> B <-> C <-> D <-> A...

// A is firstNode, D is lastNode

        if ( length == 1 )
        {
            firstNode = null;
            lastNode = null;

            firstNode.next = null;
            firstNode.prev = null;
        }

        else
        {
            Node secondNode = firstNode.next;
            Node secondToLast = lastNode.prev;

            firstNode.next = null;
            firstNode.prev = null;

            lastNode.next = null;
            lastNode.prev = null;

            secondNode.prev = null;
            secondToLast.next = null;

            firstNode = null;
            lastNode = null;
        }

That should send everything in between as candidates for garbage collection, I hope?

ShrimpCrackers
  • 4,388
  • 17
  • 50
  • 76

2 Answers2

3

As long as there are no strong references that refer to the nodes, then it doesn't matter if there are circular references "between" the nodes, the objects will still be candidates for garbage collection.

That means when there are no more local variables or static variables that hold a reference to the objects (whether they fall out of scope, you explicitly set them to null or assign them to something else) then the object will be garbage collected.

Dean Harding
  • 71,468
  • 13
  • 145
  • 180
  • There can be strong-references between the nodes (e.g. circular). The requirement for an object to unreachable (and thus reclaimable) is the anti-statement of: "A reachable object is any object that can be accessed in any potential continu- ing computation from any live thread." This is per JLS 12.6.1. JLS 12.6.1.1 contains the finer details. –  May 10 '10 at 04:11
  • I agree with your answer. I was clarifying the use of strong-references and providing a documentation source :-) –  May 10 '10 at 04:13
2

Java doesn't reference count, so it doesn't matter if the references are circular.

Java uses a mark and sweep type algorthim at higher memory densities, and a copy clear algorthim at lower densities in JVM versions 1.4, 1.5, and 1.6. The mark and sweep starts marking everything "reachable" from the main program thread, and clears and compacts whatever didn't get marked. The copy and clear copies all objects reachable by the main thread into the new memory and then clears the old blocks of memory.

Since both of these techniques are "reachable from the main thread" techniques, it doesn't matter if you make a bunch of circular references. If the references are "reachable from the main thread" then the entire circle will be marked and preserved. If a circular reference isn't reachable by the main thread, then it will eventually be cleared because it's not marked as in-use.

Java optimizes it's garbage collection via generations. For more details look here.

Java 1.7 might have a new garbage collection strategy by default. It is called G1, which is short for Garbage First. They've been playing with it in the 1.6 branch, and you can turn it on if you wish. It's a lot faster than the standard garbage collection, but it's not clear whether it's bug free, or if it will remain faster in all the important use cases. For more information, read about Garbage First

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138