Question

I am new to Java Garbage Collection and wondering if following codes will cause memory leak in Java. Why or why not? Thanks.

class ListNode {
    int value;
    ListNode next;

    public ListNode(int value) {
        this.value = value;
        next = null;
    }
}

public class Test() {

    static void tryCreateMemoryLeak() {
        ListNode l1, l2;
        for (int i = 0; i < 1000000; i++) {
            l1 = new ListNode(1);
            l2 = new ListNode(2);

            // create a circle here
            // will this circle be reclaimed? if do, when?
            l1.next = l2;
            l2.next = l1;
        }
    }

    public static void main(String[] args) {
        tryCreateMemoryLeak();
    }

}
Was it helpful?

Solution

As the Java JVM's GC is a tracing and mark-and-sweep garbage collector, not a reference counter, it's impossible to cause a memory leak in Java purely through circular references.

The reason for this is that A will reference B, B will reference A, but no other objects will reference A or B, therefore marking both A and B (during the mark phase) eligible for garbage collection.

The JVM's GC marks all objects in the heap as collectable, traces from its roots, such as static variables, classloaders and such, marks all objects reachable by this trace as not-collectable and therefore would never reach the A or B instance you allocated. Therefore, the JVM's GC will detect that A and B are eligible for garbage collection and reclaim their memory.

OTHER TIPS

Try having a look at

http://www.itcsolutions.eu/2011/02/08/tutorial-java-9-garbage-collection-and-memory-leaks/

The expatiation is pretty neat. It might be of help

A memory leak is retaining a live reference (by mistake) of something that should not be referenced anymore.

You won't fool any modern garbage collectors by just creating a complicated web of references. Garbage collectors are (and have been for quite a number of years) mature enough to deal with circular references reliably.

As a rule of thumb: Memory leaks today are never caused by the garbage collector being unable to collect unreferenced stuff - there is always a (often well concealed) live reference if something isn't collected.

The GC recognizes even circles. As soon as you do not longer reference this circle (for example by leaving the scope), the GC will eventually release the memory. Creating a memory leak in Java is...difficult. But not impossible (depending on the actual definition of memory leak).

Circular references will not cause a memory leak. The objects will be subject to garbage collection when there are no more live references to any of the objects in the chain of circular references. When the actual garbage collection takes place is implementation dependent.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top