finalize方法设置对象对对象属性的引用会发生什么

时间:2014-01-06 14:25:09

标签: java garbage-collection finalize

A的实例是垃圾收集还是永远留在内存中?

我知道如果一个对象有资格进行垃圾收集并且已经调用了它的finalize()方法,并且在这个方法中,对象变得可以通过实时执行线程访问,它不会被垃圾回收。

public class A{

  String someString = null;
  private A a=null;
  public String getSomeString() {
    return someString;
  }
  public void setSomeString(String someString) {
    this.someString = someString;
  }
  @Override
  protected void finalize() throws Throwable {
    try {
      this.a=this;
      System.out.println("final called");      
    } finally {
      super.finalize();
    }
  }
}
public static void main(String args[]) throws Exception {
  A s1=new A();
  s1=null;
  System.gc();
  System.out.println("gc called");
  ......
}

Can we switch off finalizers?启发

2 个答案:

答案 0 :(得分:4)

该分配(在finalize())方法中不会使目标对象(this)强烈可达,因此不会阻止它被垃圾回收。

另一方面,如果你这样做了:

    otherObject.a = this;

otherObject引用了一个强可访问的对象,然后赋值使this强烈可达,并且它会阻止对象被收集(当它仍然可以访问时) ...)。但是下次this无法访问时,将不会调用finalize方法。对象的finalize方法只在对象的生命周期中被调用一次。


  

我认为this.a=this会指定它的属性?如果我错了,请纠正我。

你是对的,但没有区别。你所做的只是让this指向自己。这不能让它达到......

答案 1 :(得分:2)

您添加的行

this.a=this;

不会阻止A成为GC,这个对象仍然没有像活动线程那样被引用。

尝试查看更复杂的结构:List

如果您将最后一个节点指向第一个节点(循环列表),然后设置Node head = null;,那么可能每个节点仍然从另一个节点指向,但整个列表未被引用线程和那里将被垃圾收集。

垃圾收集器不只是检查对象是否被引用,而是检查是否存在来自有效线程的引用。

底线是:

如果某个对象无法从线程中访问,则会收集垃圾。在您的情况下,A无法再访问。