黑马程序员技术交流社区

标题: finalize与system.gc() [打印本页]

作者: 仲伟    时间: 2013-5-13 16:50
标题: finalize与system.gc()
原帖的地址:http://bbs.csdn.net/topics/80089815
class person{
    public void finalize(){
        System.out.println("the object is going!");
    }
    public static void main(String[] args){
        new person();
        new person();
        new person();
        System.gc();

        System.out.println("the program is ending!");
    }
}
运行结果如下
the object is going!
the object is going!
the object is going!
the program is ending!
问题如下
1:我认为运行结果应该是
  the object is going!
  the program is ending!
  为什么强制执行回收会执行三遍?
2:谁能告诉我System.gc的运行原理?
3:finalize()怎么释放这3个匿名存储空间?
4:如果System.gc不强制运行,这3个匿名垃圾非要等到程序空闲才会被自动回收何不把这个方法直接改成手动的?
作者: 仲伟    时间: 2013-5-13 16:51
1:我认为运行结果应该是
   the object is going!
   the program is ending!
   为什么强制执行回收会执行三遍?

倒,GC 运行一次可以回收许多的垃圾,并不是执行多少遍。楼主创建的三个对象都符合收集条件,GC 在收集时调用了每一个的终止方法。

2:谁能告诉我System.gc的运行原理?

GC 是一个高度优先的后台线程,自动进行垃圾收集,执行收集的具体时刻不以程序员的意志为转移。

3:finalize()怎么释放这3个匿名存储空间?

终止方法中应该包含关闭对象使用的资源的代码(文件/数据连接),楼主的对象未使用任何特别的资源,楼主的终止方法中也不需要做什么特别的事情,终止方法是由 GC 调用的。

4:如果System.gc不强制运行,这3个匿名垃圾非要等到程序空闲才会被自动回收何不把这个方法直接改成手动的?

GC 的运行不以程序员的意志为转移,这是事实。可以想象其实现是高度复杂的,大多数情况下可以认为是有智能的,或者说比大多数人自己做好。
作者: breeze    时间: 2013-5-13 21:05
这不是优先级的问题, 是因为生成了3个对象, 这时候在内存堆区域中, 这时候你需要回收的垃圾就会有3个, 而你重写了finalize方法, 垃圾回收时是会调用这个方法的, 而object类中的System.gc(), 方法里是调用了finalize(), 但一个类加载时是会出现两个线程, 主线程(非守护线程main())和垃圾回收线程(守护线程finalize()), (守护线程是依赖于非守护线程的, 当非守护线程执行完毕, 守护线程也会随之消失), 因为你调用了System.gc()方法, 是手动开启了一个垃圾回收线程, 当主线程完毕时垃圾回收线程可能回收了两个, 这时候JVM关闭了, 所以结果还有可能是下面这样:
the program is ending!
the object is going!
the object is going!请按任意键继续. . .

注意, 调用gc()不是只会执行一次finalize(), 而是会将所有垃圾对象回收, 从而调用每个对象的finalize(), finalize()是在对象销毁时调用的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2