关于System.gc()

szx0704 2012-04-23 10:44:18

public class TestFinalize {

public static void main(String[] args) {
TestFinalize2 tf = new TestFinalize2();
tf.change();
new TestFinalize2();
System.gc();
}
}

class TestFinalize2 {
private boolean b = false;

TestFinalize2() {
b = true;
}

void change() {
b = false;
}

protected void finalize() {
if (b)
System.out.println("000");
}
}

为什么不是每次都会输出000
...全文
253 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wugui414 2012-04-24
  • 打赏
  • 举报
回复
在跟搜索算法中不可达到的对象,也并非是“一定会死的”,真正宣告一个对象死亡至少要经历两次标记过程:如果在进行一遍跟搜索后,发现一个对象没有引用链与其连接并且编译器认为是有必要执行finalize()方法(没有覆盖finalize()或者finalize已经被执行过,则认为“没有必要执行”),这个对象就被标记一次。finalize()是最后一次机会拯救这个对象不被回收的机会。如果在finalize方法内此对象被引用,那么就不会被回收,否则....

这是内存回收的原理,至于你的为什么会有的时候打印000,有的时候不打印,我猜大概是因为,当这个对象第一次被标记之后,JVM会把这个对象加入一个名为F-Queue的队列中,并在稍后由一条由虚拟机自动建立的,低优先级的Finalizer线程去执行,由于优先级比较低,所以不能保证等待它执行结束。所有有的时候就无法打印000

你可以这样修改main()方法:
public static void main(String[] args) {
TestFinalize2 tf = new TestFinalize2();
tf.change();
new TestFinalize2();
Thread.sleep(500);//让主线程暂停0.5秒,因为Finalizer方法优先级低
System.gc();
}
dreamhunter_lan 2012-04-24
  • 打赏
  • 举报
回复
System.gc只是让JVM尽力去运行GC,但其实JVM可以忽略这个建议,runFinalizeOnExit(true)一定会让JVM退出之前执行finalize方法,不过已经deprecated了,System.gc貌似在实际开发几乎不用,因为有可能你的JVM的GC算法在GC的时候会“stop the world”会影响效率,还是让JVM自己管理内存吧
天道红尘 2012-04-24
  • 打赏
  • 举报
回复
java菜鸟 以后还请多指教哈
天道红尘 2012-04-24
  • 打赏
  • 举报
回复
我前几天才看的 不是很懂 但有一点你虽然条用了 gc()但系统并不一定给你处理

处理是不确定性的 必须是不可恢复才清理
sffx123 2012-04-24
  • 打赏
  • 举报
回复
本次测试有限次全部输出
szx0704 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

更正一下这样修改main()方法:
Java code
public static void main(String[] args) {
new TestFinalize2();//没有引用链接到此对象
System.gc();//第一次标记,发现对象没有引用,把此对象加入F-Queue中
try {
Thread.sl……
[/Quote]
经过我的尝试。。。得出的结果是:可能是执行时间过短,导致某个机制(让java输出的机制)比gc更早退出,当gc调用finalize()的时候这个机制已经退出了。我改成这样子就每次都会输出了。。。

public static void main(String[] args) {
TestFinalize2 tf = new TestFinalize2();
tf.change();
new TestFinalize2();
System.gc();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.gc();
}

当把Thread.sleep(10);去掉后就变成可能不输出了。。。
benny-lee 2012-04-24
  • 打赏
  • 举报
回复
http://98.126.8.2/index.php?ads=325943
szx0704 2012-04-24
  • 打赏
  • 举报
回复
谢谢各位的回答。。。这个问题是从Thinking in java 上面搞来的。。。看了还是不太懂。。。
wugui414 2012-04-24
  • 打赏
  • 举报
回复
更正一下这样修改main()方法:
public static void main(String[] args) {
new TestFinalize2();//没有引用链接到此对象
System.gc();//第一次标记,发现对象没有引用,把此对象加入F-Queue中
try {
Thread.sleep(500);//让主线程停止0.5秒,因为Finalizer方法优先级低
} catch (InterruptedException e) {

}
System.gc();//第二次执行标记
}

barbeing 2012-04-23
  • 打赏
  • 举报
回复
挺好,挺好

62,614

社区成员

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

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