2014-01-06 36 views
0

A类的实例是垃圾回收还是永久保留在内存中?当finilize方法设置对象对对象属性的引用时会发生什么

我知道如果一个对象符合垃圾回收的条件,并且它的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?

+0

this.a =这不会阻止gc,仍然没有提及这个对象的某些'生命',因此它会是gc。如果你想从别的东西(如活线程)中引用它,那么它可能会存活下来。 – Vladp

+0

@Vladp做出这个答案,你会得到我的最高票... –

+0

@Vladp我认为this.a =这分配给它的属性的引用? 纠正我,如果我错了.. –

回答

2

您添加

this.a=this; 

线是不是会阻止A被GC,这个目的仍旧没有从合法的东西就像一个活的线程引用。

尝试寻找一个更复杂的结构:List

如果你点的最后一个节点到第一(循环链表),然后设置你Node head = null;那么也许依然从其他节点指出每个节点,但整个列表不会从活动线程引用,并且会收集垃圾。

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

底线是:

如果一个对象是从一个线程是垃圾回收不可达。在你的情况下,A无法再到达。

4

那项任务(在finalize())方法不会使目标对象(this)强可到达,所以它不会阻止它被垃圾收集。

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

otherObject.a = this; 

otherObject称为强可及对象,然后分配使this强可到达,它会阻止该对象被收集(虽然它保持可达...)。但下一次this变得无法访问,finalize方法将不会被调用。对象的finalize方法在对象的生命周期中只被调用过一次。


我觉得this.a=this参考分配给它的财产?纠正我,如果我错了..

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

+0

所以有一种方法,实际上在java内存泄漏?不错。 – Vladp

+0

@Vladp - 我觉得不是你的意思。 –

+0

如果你故意调用finalize(并使用otherObject.a = this),然后再次无法访问,gc不会收集它,它会创建内存泄漏。错误? – Vladp

相关问题