对象成为垃圾的条件
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
写的真不错,赞下作者。