views:

119

answers:

4

I am running the following code every two minutes via a Timer:

object = new CustomObject(this);

Potentially, this is a lot of objects being created and a lot of objects being overwritten. Do the overwritten objects get garbage collected, even with a reference to itself being used in the newly created object?

I am using JDK 1.6.0_13.

Thanks for the help.

+2  A: 

We'd need to know what was going on inside the constructor to answer the question fully.

But generally, as long as nothing retains a reference to the old object when the new one is created, it will be available for garbage collection, even if the old object is used in the process of creating the new one.

For example:

class Foo {
    private String name;

    Foo() {
        this.name = null;
    }

    Foo(Foo f) {
        this.name = f.name;
    }

    public void setName(String n) {
        this.name = n;
    }

    public Foo spawn() {
        return new Foo(this);
    }
}

This won't retain references to the old Foo when the new Foo is constructed, so the old Foo can be GC'd:

Foo f;

f = new Foo(); // The first Foo
f.setName("Bar");

while (/* some condition */) {
    // Periodically create new ones
    f = f.spawn();
}

Whereas if Foo looked like this instead:

class Foo {
    private Foo parent;

    Foo() {
        this.parent = null;
    }

    Foo(Foo f) {
        this.parent = f;
    }

    public Foo spawn() {
        return new Foo(this);
    }
}

...then each newly spawned Foo would have a reference to the previous Foo and none of them would be available for GC.

T.J. Crowder
Thanks, this clears it up. I didn't know if keeping a reference to a live object would allow the other objects to be garbage collected.
stjowa
A: 

There are no overwritten objects. object is simply bound to a new instance of Object. As long as there are no additional references to the pre-existing instance it will get removed by GC at some point. It doesn't matter if that child is keeping a reference to it's parent. Once it becomes unreachable it will be marked for GC.

I'm guessing it's not really java.lang.Object that you mean here.

Trevor Tippins
+2  A: 

Java uses a "mark and sweep" garbage collector. Basically that means: if it's reachable by your running code, it's not eligible for garbage collection, otherwise it is.

Michael Borgwardt
java hasn't used mark and sweep as the main gc in a while. it uses generations now. not the _method_ of GC really matters. java guarantees in the spec that if it is reachable, it is not GC'ed, otherwise it is/(may be).
james
@james: the method does matter: the "reachable" criterium can only be fulfilled by mark and sweep or similar approaches (which java does use), not by reference counting.
Michael Borgwardt
+1  A: 

It depends on what you do with the object in the constructor. If you keep references to it in the newly created object, this will prevent the garbage collector to reclaim the memory.

The example below demonstrates this:

class Inner {
    public Inner() {
            this.ref = null;
    }

    public Inner(Inner ref) {
            this.ref = ref;
    }

    Inner ref;
}

class Test {
    public static void main(String [] args) {
            Inner x = new Inner();

            while(1==1) {
                    x = new Inner(x);
            }
    }
}

In java, any reachable object from a "live" object will not be a candidate for garbage collection.

the_void