`
闫老三
  • 浏览: 102692 次
社区版块
存档分类
最新评论

关于垃圾回收的机制与机理之孤岛垃圾 .

 
阅读更多

对象成为垃圾的条件

1.对于非线程对象来说 当所有的活动线程都不可能访问到这对象时,变成垃圾
2.对于线程对象来说 除了上一条之外,还要求吃线程本身已经死亡或者还处于新建状态,才是垃圾,才能被回收

 

千万不要片面的认为“没有引用指向的对象就是垃圾,有引用指向的就不是垃圾”是对的

孤岛垃圾就是个反驳的例子

class Island{
    public Island brother;
}

//运行下面代码片段
    Island il = new Island();
    Island i2 = new Island();
    Island i3 = new Island();
    
    il.brother = i2;
    i2.brother = i3;
    i3.brother = i1;
    
    i1 = null;
    i2 = null;
    i3 = null;
    
    // 这样 三个对象循环指向  但他们形成了孤岛 所以已经成为垃圾 

 

就垃圾回收非线程的例子

class Island{
    public Island brother;
    String name;
    public Island(){
    }
    public Island(String name){
        this.name = name;
    }
    public void finalize(){
        System.out.println(this.name + "对象成为垃圾,被收集");
    }
    public void testIsland(){
        Island i1 = new Island("孤岛中的 O1");
        Island i2 = new Island("孤岛中的 O2");
        Island i3 = new Island("孤岛中的 O3");
        
        i1.brother = i2;
        i2.brother = i3;
        i3.brother = i1;
        
        i1 = null;
        i2 = null;
        i3 = null;
        // 这样 三个对象循环指向  但他们形成了孤岛 所以已经成为垃圾 
        
        System.gc();//可以看到 三个对象很快被收集,但程序过了10s才结束
        try{
            Thread.sleep(10000);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

public class Test{
    public static void main(String[] args){
        new Island().testIsland();
    }
}

 

线程垃圾例子

public class Test{
	public static void main(String[] args){
//		new Island().testIsland();
		new RubbishThread().testRT();
	}
}

class RubbishThread extends Thread{
	
	RubbishThread brother;
	String rtName;
	
	public RubbishThread(){
		
	}
	
	public RubbishThread(String name){
		this.rtName = name;
	}
	
	public void run(){
		System.out.println(this.rtName + "线程启动了");
		try{
			Thread.sleep(1000);
		}catch(Exception e){
			e.printStackTrace();
		}
		System.out.println(this.rtName + "线程结束");
	}
	
	public void finalize(){
		System.out.println(this.rtName + "成为垃圾被收集");
	}

	public void testRT(){
		RubbishThread rt1 = new RubbishThread("孤岛中的rt1线程");
		RubbishThread rt2 = new RubbishThread("孤岛中的rt2线程");
		RubbishThread rt3 = new RubbishThread("孤岛中的rt3线程");
		
		rt1.brother = rt2;
		rt2.brother = rt3;
		rt3.brother = rt1;
		
		rt1.start();
		
		rt1 = null;
		rt2 = null;
		rt3 = null;
		
		System.out.println("---------对无引用但活着的线程进行垃圾收集--------------");
		System.gc();
		
		try{
			Thread.sleep(2000);//主线程休眠2s
		}catch(Exception e){
			e.printStackTrace();
		}
		
		System.out.println("---------对无引用死亡的线程进行垃圾收集--------------");
		System.gc();
		
		try{
			Thread.sleep(1000);//主线程休眠1s
		}catch(Exception e){
			e.printStackTrace();
		}	
	}
// 执行结果
//	---------对无引用但活着的线程进行垃圾收集--------------
//	孤岛中的rt1线程线程启动了
//	孤岛中的rt1线程线程结束
//	---------对无引用死亡的线程进行垃圾收集--------------
//	孤岛中的rt3线程成为垃圾被收集
//	孤岛中的rt2线程成为垃圾被收集
//	孤岛中的rt1线程成为垃圾被收集
	
//解释:执行第一次垃圾收集由于线程rt1还没有死亡,虽然形成了孤岛垃圾 
//      但其中的对象可以被活动的进程访问到,整个孤岛不是垃圾
//		执行第二次垃圾收集时rt1已经死亡 整个孤岛成为垃圾,3个线程都被收集
//		没有启动的线程与死亡的线程一样,只要满足普通对象成为垃圾的条件就是垃圾
	
}

 原文地址;http://blog.csdn.net/kindazrael/article/details/4630159 

写的真不错,赞下作者。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics