黑马程序员技术交流社区

标题: finalize方法和垃圾回收器的原理 [打印本页]

作者: 徐梦侠    时间: 2012-10-19 12:44
标题: finalize方法和垃圾回收器的原理
本帖最后由 徐梦侠 于 2012-10-19 14:52 编辑

如果不含代码stu=new Student("李四");System.out.println(stu.toString());,打印结果就是Finalize Object : Student : 张三。
说明空间已经释放,那应该先打印Finalize Object : Student : 张三,可为什么结果不是这样呢?

class Student{
    private String name;
    public Student(String name){
            this.name = name;
    }
    public String toString(){
            return("Student : " + this.name);
    }
    public void finalize() throws Throwable{
            System.out.println("Finalize Object : " + this);
    }
}
class SystemDemo02{
public static void main(String[] args){
   Student stu = new Student("张三");
   stu = null;                //断开引用
   //如果让线程等待1分钟,即运行一段时间,再运行系统垃圾回收就会调用fianlize方法了
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.gc();        //强制释放空间
   stu=new Student("李四");
   System.out.println(stu.toString());
}
}
为什么打印结果会是:
Student : 李四
Finalize Object : Student : 张三

作者: 赵云柯    时间: 2012-10-19 14:37
上面的程序如果多试验几次就会发现,两条语句的打印顺序是随机的。

出现这种情况的原因是,程序在调用System.gc();语句时,虚拟机会根据需要在单独的线程中自动执行回收过程。

也就是说,主线程负责打印"Student : 李四",而用来回收垃圾的线程负责打印"Finalize Object : Student : 张三"。

两个线程抢占CPU是随机的,所以两条语句的打印顺序也是随机的。
作者: 徐梦侠    时间: 2012-10-19 14:52
赵云柯 发表于 2012-10-19 14:37
上面的程序如果多试验几次就会发现,两条语句的打印顺序是随机的。

出现这种情况的原因是,程序在调用Syst ...

受教了,应该就是用的单独的线程执行回收过程
作者: 孙含庆    时间: 2012-10-19 15:04
class Student{
    private String name;
    public Student(String name){
            this.name = name;
    }
    public String toString(){
            return("Student : " + this.name);
    }
    public void finalize() throws Throwable{
            System.out.println("Finalize Object : " + this);
    }
}
class SystemDemo02{
public static void main(String[] args){
   Student stu = new Student("张三");
   stu = null;                //断开引用
  
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.gc();       //这也不是强制启动垃圾回收,只是显式的启动了GC垃圾回收,        
                              //但是jvm虚拟机并不会立即去执行,也可能会立即执行,所以输出结果不一样。   
    stu=new Student("李四");
   System.out.println(stu.toString());
}
}





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