之前问了一个相关的问题,两个相互指向对方的对象,是否可以被垃圾回收,通过大家的讨论,最后了解到,由于他们两个没有外部引用指向他们,他们会被一起回收掉。那么另外一种情况,一个对象,只有一个指向自己的引用,这种情况,按道理来说应该和上面的情况类似,这个对象可以被回收,但是实际写一个代码测试,那个对象却怎么都没有被回收,到底是怎么回事呢?代码如下:public class Test
{
  private String name;
  private Test ref;
  
  public Test(String name)
  {
    this.name = name;
    this.ref = null;
  }
  
  public void setRef(Test t)
  {
    this.ref = t;
  }
  
  public void finalize() throws Throwable
  {
    System.out.println(this.name + " is garbage collected!");
    super.finalize();
  }
  
  public static void main(String[] args)
  {
    Test test = new Test("Test object");
    test.setRef(test);
    System.gc();// 不管叫多少次gc,输出都没有打印对象被回收那句话
    System.gc();
    System.gc();
    System.gc();
    System.out.println("Test object is garbage collected?");
  }
}

解决方案 »

  1.   

    GC 只要发现一个对象用 强引用就不会回收他 而一般的应用就是一种强引用
    开下面两段代码的区别  运行的话有点危险,机子不好会死机,可以改成晕多少秒结束
    看运行结果就知道  class s {
    private String str;
    public s(){
    str = "garbage collected";
    }
      public void finalize() throws Throwable
      {
        System.out.println(this.str);
        super.finalize();
      }
    }
    new s(); // 没有强引用,会回收
    while(true){
    System.gc();
    }
    class s {
    private String str;
    public s(){
    str = "oh I go";
    }
      public void finalize() throws Throwable
      {
        System.out.println(this.str);
        super.finalize();
      }
    }
    s t = new s();// 不会回收,t就是强引用
    while(true){
    System.gc();
    }
      

  2.   

    知道了吧 你那个引用死环 不会影响Java虚拟机的垃圾回收
    垃圾回收 是反向的 从内存堆对象区 的对象开始 逆向树状搜索有没有强引用 
    如果没有的就回收 
      

  3.   

    public class Test {    private String name;
        private Test ref;    public Test(String name) {
            this.name = name;
            this.ref = null;
        }    public void setRef(Test t) {
            this.ref = t;
        }    public void finalize() throws Throwable {
            System.out.println(this.name + " is garbage collected!");
            super.finalize();
        }    public static void main(String[] args) {
            for (int i = 0; i < 10000000; i++) {
            }
            Test test = new Test("Test object");
            test.setRef(test);
            System.gc();
             System.out.println("Test object is garbage collected?");
        }
    }
      

  4.   

    当一个或多个对象形成隔离岛的时候,也是会被回收的。
    如A引用B,B引用C,C引用A。
      

  5.   

    Test test =当前线程还有 test 的引用。
    我用JDK1.6,已经被回收了。    public static void main(String[] args) throws InterruptedException {
            g();
            System.gc();
        }    private static void g() {
            Test test = new Test("Test object");
            test.setRef(test);
        }
      

  6.   

    会回收的,java虚拟机也用了火车箱算法,一起回收交叉引用的对象
      

  7.   

    因为你GC的时候, test引用的生命周期还没有结束,你还可以通过test引用访问这个对象.    Test test = new Test("Test object");
        test.setRef(test);把这两句放到一个单独的函数就行了.
      

  8.   

    选E
    这两个对象, 如果没有第三方引用到其中之一, 也就是外界无法访问到这两对象 
    只有互相引用的话,这两个对象会连在一起成为垃圾,可以被回收测试程序:public class Test
    {
        public static void main(String[] args) 
        {              
            Snoochy snoog = new Snoochy();                        
            snoog = null;
            while(true)
                System.gc();
        }
    }class Boochy 
    {                                        
        Snoochy snooch; 
        public Boochy(Snoochy s) 
        { 
            snooch = s;
        }          
        
        public void finalize()
        {
            System.out.println("Boochy garbage collected.");
        }
    }class Snoochy 
    {                                      
        Boochy booch;                                        
        public Snoochy() 
        { 
            booch = new Boochy(this); 
        } 
        
        public void finalize()
        {
            System.out.println("Snoochy garbage collected.");
        }
    }
    程序输出:
    Boochy garbage collected.
    Snoochy garbage collected.