下面这个测试程序,用来测试垃圾回收的速度,为什么在电脑上执行时,得到的输出是:
This object is uncollected!
It works!
这个结果说明gc()方法一执行,String对象马上就被回收了,为什么会这么快?更奇怪的是,有的人电脑上测试的结果却是:
This object is uncollected!
This object is uncollected!
This object is uncollected!
It works!
为什么会不一样呢?哪位前辈能给点提示?
import java.lang.ref.*;public class Test
{
public static void main(String[] args)
{
String a = new String("This object is uncollected!");
WeakReference b = new WeakReference(a);
System.out.println(b.get());
//Remove strong reference to the String
a = null;
//Call garbage collector...
System.gc();
//Shouldn't the String be finalized?
if(b.get() == null)
System.out.println("It works!");
else // This is the condition that is executed
System.out.println(b.get());
System.exit(0);
}
}
This object is uncollected!
It works!
这个结果说明gc()方法一执行,String对象马上就被回收了,为什么会这么快?更奇怪的是,有的人电脑上测试的结果却是:
This object is uncollected!
This object is uncollected!
This object is uncollected!
It works!
为什么会不一样呢?哪位前辈能给点提示?
import java.lang.ref.*;public class Test
{
public static void main(String[] args)
{
String a = new String("This object is uncollected!");
WeakReference b = new WeakReference(a);
System.out.println(b.get());
//Remove strong reference to the String
a = null;
//Call garbage collector...
System.gc();
//Shouldn't the String be finalized?
if(b.get() == null)
System.out.println("It works!");
else // This is the condition that is executed
System.out.println(b.get());
System.exit(0);
}
}
This object is uncollected!
This object is uncollected!
This object is uncollected!
It works! 可问题在于,在楼主的电脑里运行这段程序,出现的结果并不是预期那样,而是:
This object is uncollected!
It works! 多次运行,出现同样的结果,这个结果说明,垃圾回收在System.gc()方法后就立刻执行了,这正是奇怪的地方,哪位大侠知道原因的么?
说得简单点,就是WeakReference会把a的引用间接的传给b。
注意这个间接。所以当你吧a=null的时候b没有立刻就变成null。
直到垃圾回收器运行的时候这个间接的引用才会变成null,同时b也变成了null。又因为:System.gc();只是建议jvm去运行垃圾回收器,而垃圾回收器,具体的运行时间
我们的程序是无法控制的。所以,上面的程序,会出现那些不同的结果。
是无法控制的 LS说的正确
This object is uncollected!
This object is uncollected!
This object is uncollected!
It works!
这种结果,我个人认为不可能。除非运行程序的那台电脑的JVM有问题。即使在GC以后,a没有被立刻回收,结果也只可能是:
This object is uncollected!
This object is uncollected! 你没有写循环,程序不可能跳到前面再执行一次GC。
下面的程序可以证明这一点,每次sleep之前的GC调用都导致对象立即被回收。
public class GCTest {
public static void main(String[] args) throws InterruptedException {
Obj obj1 = new Obj();
Obj obj2 = new Obj();
System.out.println("begin.");
Thread.sleep(2000);
obj1 = null;
System.gc();
Thread.sleep(2000);
obj2 = null;
System.gc();
Thread.sleep(2000);
System.out.println("end.");
}
}class Obj {
public void finalize() {
System.out.println(this + " is finalized.");
}
}尽管如此,对GC抱不信任态度还是明智的,特别地,不要重要的程序逻辑建立在对GC的信任上。