class Book{
boolean checkedOut=false;
Book(boolean checkout){
checkedOut =checkout;
}
int checkIn(){
checkedOut=false;
return 1;
}
protected void finalize(){
if(checkedOut){
System.out.println("error checkedout");
}
}
}
public class TerminationCondition {
public static void main(String[] args){
Book novel =new Book(true);
novel.checkIn();
new Book(true);
System.gc();
}
}
thinking in java中的一段代码。 书是英文版的,没看太懂
不过大致是在讲 说gc会调用finalize()函数
树上讲这段代码会执行重载后的finalize()函数中的语句,即输出error checkout
但是我在myecplise中跑了一下  
没有任何输出 
我想问下 这是怎么回事还有 gc和finnalize到底是什么关系

解决方案 »

  1.   

    System.gc()是要求jvm执行垃圾回收,这时候会调用这个类的finalize()方法,如果你不强制jvm执行垃圾回收,这时候是不会调用finalize()方法的,在这个代码中,会执行finalize()方法,并且在这段代码里,novel1还引用一个对象,所以第一个对象是有用的,不会被收集,但是第二个对象是匿名对象,所以强制回收的时候,会收集第二个,即true,会有输出的
      

  2.   

    (1)问题:finalize()函数是干嘛的?Java不是有Garbage Collection(以下简称gc)来负责回收内存吗?
    回答:
    gc只能清除在堆上分配的内存(纯java语言的所有对象都在堆上使用new分配内存),而不能清除栈上分配的内存(当使用JNI技术时,可能会在栈上分配内存,例如java调用c程序,而该c程序使用malloc分配内存时).因此,如果某些对象被分配了栈上的内存区域,那gc就管不着了,对这样的对象进行内存回收就要靠finalize().
    举个例子来说,当java 调用非java方法时(这种方法可能是c或是c++的),在非java代码内部也许调用了c的malloc()函数来分配内存,而且除非调用那个了free() 否则不会释放内存(因为free()是c的函数),这个时候要进行释放内存的工作,gc是不起作用的,因而需要在finalize()内部的一个固有方法调用它(free()).
    finalize的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.(2)问题:finalize()在什么时候被调用?
    回答:有三种情况1.所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候.
    2.程序退出时为每个对象调用一次finalize方法。
    3.显式的调用finalize方法除此以外,正常情况下,当某个对象被系统收集为无用信息的时候,finalize()将被自动调用,但是jvm不保证finalize()一定被调用,也就是说,finalize()的调用是不确定的,这也就是为什么sun不提倡使用finalize()的原因.
      

  3.   

    finalize是为了拯救对象用的,而且只能被调用一次。强烈建议初级程序员,非系统级程序员不要关心finalize的详情。了解一下GC就好了。
      

  4.   

    我试了,输出了,你可以 在 main 最后加个 Thread.sleep(10000);
    gc 线程本是 demon 线程,你的main线程结束了,他就思密达了
      

  5.   

    五楼正解
    线程什么的真的不懂小弟刚开始学java
      

  6.   

    novel所引用的对象在运行方法时不会被回收
      

  7.   

    哥来给你详细解释一下
    1、System.gc是建议jvm进行垃圾回收,jvm可以不睬这个建议。且可以用jvm参数禁用System.gc的建议2、finalize如果被重写了花,在该对象被垃圾回收的第一次肯定会执行。当然垃圾回收有可能使得该对象复活3、如果垃圾收集器回收曾经被复活的对象,那么finalize不会被调用第二次4、finalize在程序运行期间可能永远也得不到调用
      

  8.   

         呵呵  这是gc的回收问题   手工调用gc命令以后  java虚拟机会在之后开始回收
     垃圾资源是没错   但是虚拟机不会马上执行回收的   在你的程序中开启另一个线程,
    里面执行一个循环你就能开到你的  在回收时要执行的代码了  但是代码执行过程很短
    你要注意看屏幕输出
      

  9.   

    为什么在我的机子上就可以直接的输出,个人认为输出的应该是false,这里可以把你的程序稍作更改就可以了class Book {
    boolean checkedOut = false; Book(boolean checkout) {
    checkedOut = checkout;
    } int checkIn() {
    checkedOut = false;
    return 1;
    } protected void finalize() {
    if (checkedOut) {
    //System.out.println("error checkedout");
    System.out.println("error checkedout"+"\t"+this.checkIn()+"\t"+this.checkedOut);
    }
    }
    }public class TerminationCondition {
    public static void main(String[] args) {
    Book novel = new Book(true);
    novel.checkIn();
    new Book(true);
    //novel = null;
    //System.out.println(novel.checkedOut);
    System.gc();
    }
    }
    输出结果:
    error checkedout 1 false
    在new book(true)之后,第一个对象的任务已经完成了,就要将他回收了,就相当于断开了第一个对象的一怒用,就要将他收集了,还有引入finalize的目的是为了,在一个对对象被回收之前要进行某种的操作。
      

  10.   

    还没虚拟机垃圾回收呢,你的程序就执行完了,想看到执行finalize的话,让程序休息几秒钟就可以看到输出了
    public static void main(String[] args) {
            Book novel = new Book(true);
            novel.checkIn();
            new Book(true);
            System.gc();
            try {
                Thread.sleep(10000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }