这会在JVM中收集垃圾吗?

时间:2010-06-17 13:59:56

标签: java memory-leaks garbage-collection

我通过计时器每两分钟运行以下代码:

object = new CustomObject(this);

潜在地,这是创建了许多对象并且许多对象被覆盖。被覆盖的对象是否被垃圾收集,即使在新创建的对象中使用了自身的引用?

我使用的是JDK 1.6.0_13。

感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

我们需要知道构造函数内部发生了什么才能完全回答这个问题。

但一般来说,只要在创建新对象时没有保留对旧对象的引用,它就可用于垃圾收集,即使旧对象在进程中使用创建新的。

例如:

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);
    }
}

在构建新的Foo时,这不会保留对旧Foo的引用,因此旧的Foo可以是GC的:

Foo f;

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

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

如果Foo看起来像这样:

class Foo {
    private Foo parent;

    Foo() {
        this.parent = null;
    }

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

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

...然后每个新生成的Foo都会引用之前的Foo,并且 none 将可用于GC。

答案 1 :(得分:2)

Java使用“标记和扫描”垃圾收集器。基本上这意味着:如果你的运行代码可以访问它,它就没有资格进行垃圾收集,否则它就是。

答案 2 :(得分:1)

这取决于你在构造函数中对对象做了什么。如果在新创建的对象中保留对它的引用,这将阻止垃圾收集器回收内存。

以下示例说明了这一点:

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);
            }
    }
}

在java中,来自“实时”对象的任何可到达对象都是垃圾收集的候选对象。

答案 3 :(得分:0)

没有被覆盖的对象。 object只是绑定到Object的新实例。只要没有对预先存在的实例的其他引用,它就会在某些时候被GC删除。如果那个孩子保持对其父母的引用并不重要。一旦无法访问,它将被标记为GC。

我猜你的意思并不是java.lang.Object