为什么垃圾回收【garbage collection】速度这么快?

bigbro001 2009-01-09 03:35:13
下面这个测试程序,用来测试垃圾回收的速度,为什么在电脑上执行时,得到的输出是:
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);
}
}
...全文
124 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhengpeiyong 2009-01-10
  • 打赏
  • 举报
回复
关注

success000 2009-01-10
  • 打赏
  • 举报
回复
友情up
Dan1980 2009-01-10
  • 打赏
  • 举报
回复
虽然Sun的文档都声明不要期望GC能立刻回收垃圾对象,但实际上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的信任上。
Dan1980 2009-01-10
  • 打赏
  • 举报
回复
出现:
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。
bigbro001 2009-01-10
  • 打赏
  • 举报
回复
非常感谢大家的建议,看来gc这个东西说不清楚。。。
酒剑仙 2009-01-09
  • 打赏
  • 举报
回复
GC()
是无法控制的 LS说的正确
wtmiao000 2009-01-09
  • 打赏
  • 举报
回复
在我看完WeakReference的源码后发现问题是这样的:
说得简单点,就是WeakReference会把a的引用间接的传给b。
注意这个间接。所以当你吧a=null的时候b没有立刻就变成null。
直到垃圾回收器运行的时候这个间接的引用才会变成null,同时b也变成了null。

又因为:System.gc();只是建议jvm去运行垃圾回收器,而垃圾回收器,具体的运行时间
我们的程序是无法控制的。所以,上面的程序,会出现那些不同的结果。
kao331431214 2009-01-09
  • 打赏
  • 举报
回复
楼主你的那个程序垃圾回收器并没有出现哦
System.out.println("It works!");
这条语句出现了的确是a b都为空了
但是在堆内存中的"This object is uncollected!"并没有被回收哦

我来说说具体的经过吧
一开始栈内存中的a指向了对内存中的"This object is uncollected!"
然后栈内存中的b指向了a
后面a指向null 由于b指向a 即b也为null
但是堆内存中的"This object is uncollected!"并没有改变

GC相当你打电话给环卫局 叫他们来回收垃圾了 开始环卫局那个时间来我们就控制不了了
bigbro001 2009-01-09
  • 打赏
  • 举报
回复
2楼到5楼都误会楼主的意思了,正是因为gc的回收并不是即时的,所以执行以上程序,预期的输出结果应该是:
This object is uncollected!
This object is uncollected!
This object is uncollected!
It works!

可问题在于,在楼主的电脑里运行这段程序,出现的结果并不是预期那样,而是:
This object is uncollected!
It works!

多次运行,出现同样的结果,这个结果说明,垃圾回收在System.gc()方法后就立刻执行了,这正是奇怪的地方,哪位大侠知道原因的么?
wuhailin2005 2009-01-09
  • 打赏
  • 举报
回复
System.gc();虽然使用了这句话,这只不过是建议jvm进行内存回收,jvm进行垃圾回收的时候并不是我们自己可以控制的,如果我们自己可以回内存那么我们的jvm的机制就和C++回收机制有些类似了,所以虽然你使用了这句话内存并不会真正的回收。如有疑问可以进一步交流。
bigbro001 2009-01-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xyz20003 的回复:]
因为gc不是实时的,你调用了也只是通知jvm需要回收,到底他什么时候执行回收,谁也不知道。
[/Quote]
问题是,跑了好几次,每次都是立刻就回收掉了,令人费解,难道是因为机器内存不够?512MB内存,除了IE和IDE,没有运行任何其他耗内存的程序啊~
kokobox 2009-01-09
  • 打赏
  • 举报
回复
其实即使你写了System.gc();也并没有真正的调用gc

所以一闪而过,而gc并没有运行

临远 2009-01-09
  • 打赏
  • 举报
回复
因为gc不是实时的,你调用了也只是通知jvm需要回收,到底他什么时候执行回收,谁也不知道。
ty_fzpb 2009-01-09
  • 打赏
  • 举报
回复
关注……

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧