【发布时间】:2010-06-17 13:59:56
【问题描述】:
我通过计时器每两分钟运行一次以下代码:
object = new CustomObject(this);
这可能是创建了很多对象并覆盖了很多对象。被覆盖的对象是否会被垃圾回收,即使在新创建的对象中使用了对自身的引用?
我使用的是 JDK 1.6.0_13。
感谢您的帮助。
【问题讨论】:
标签: java memory-leaks garbage-collection
我通过计时器每两分钟运行一次以下代码:
object = new CustomObject(this);
这可能是创建了很多对象并覆盖了很多对象。被覆盖的对象是否会被垃圾回收,即使在新创建的对象中使用了对自身的引用?
我使用的是 JDK 1.6.0_13。
感谢您的帮助。
【问题讨论】:
标签: java memory-leaks garbage-collection
我们需要知道构造函数内部发生了什么才能完全回答这个问题。
但一般情况下,只要在创建新对象时没有保留对旧对象的引用,它就可以用于垃圾回收,即使在处理过程中使用了旧对象也是如此创建新的。
例如:
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'd:
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 并且没有一个可用于GC。
【讨论】:
Java 使用“标记和清除”垃圾收集器。基本上这意味着:如果您的运行代码可以访问它,则它不符合垃圾收集的条件,否则它是。
【讨论】:
这取决于你在构造函数中对对象做了什么。如果在新创建的对象中保留对它的引用,这将阻止垃圾收集器回收内存。
下面的例子证明了这一点:
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 中,任何来自“活动”对象的可达对象将不成为垃圾回收的候选对象。
【讨论】:
没有被覆盖的对象。 object 只是绑定到一个新的 Object 实例。只要没有对预先存在的实例的额外引用,它就会在某个时候被 GC 删除。该孩子是否保留对其父母的引用并不重要。一旦它变得无法访问,它将被标记为 GC。
我猜你的意思不是真的java.lang.Object。
【讨论】: