我觉得i从来没有增加过,虽然它有i=+created 但是create初始值是0,在程序中又没有增加它的值,所以用i==47会进入死循环~!

解决方案 »

  1.   

    不好意思,说错了,是i永远不会进入i==47那个判断中,f永远不会得到true所以会进入死循环~!
      

  2.   

    是不是这个意思:当主类的while循环执行一次时,i值就增加1了。而垃圾回收器的第一次执行时i>47了。所以就进入死循环了。
      

  3.   

    Thinking in Java 已经说的很清楚了. 垃圾回收器是自己来决定什么时候来回收垃圾的,
    什么时候调用 finalize()方法也是不确定的. 不同的 JDK 版本的Java 虚拟机运行同一个这样的程序也会有不同的结果. 在我的机器上 JDK 1.4.1 b26, 结果是在创建2462个Chair对象后, i 就等于47了. 但是在你的机器上, i可能要等很才可能增加到47, 接果也会不同. 这其中还牵扯到多线程,
    1 System.out.println("Beginning to finalize after"+ created+ "Chairs have been created");2 System.out.println("Finalizing Chair#47,"+created+"Chair have been created");
    这两条语句中输出的 created 是不一样的. 
    因为垃圾回收器和你的程序是在两个不同的线程运行的, 当第一个语句被打印后, 你的
    主程序可能(注意是可能)会继续创建其它Chair对象, 当JVM觉得现在应该继续垃圾回收器的
    线程时候, 第二条语句才会被输出.
    而且你程序中有错误(可能是你输入错误),我给你纠正了. 顺便问一下, 我估计你是在用第二版本的 Thinking in java
      //Demonstration of the garbage
      //collector and finaliztion
    class Chair{
       static boolean gcrun=false;
       static boolean f=false;
       static int created=0;
       static int finalized=0;
       int i;
       Chair(){
           i=++created;
           if (created==47)
               System.out.println("Created 47");
        }   public void finalize(){
          if(!gcrun){
               //The first time finalize()is called:
               gcrun=true;
               System.out.println("Beginning to finalize after"+ created+ "Chairs have been created");
          }
     
         if(i==47){
                  System.out.println("Finalizing Chair#47,"+created+"Chair have been created");
                 f=true;
           }
          finalized++;
       }
    }public class Garbage
    {
      public static void main(String args[])
            {
                while(!Chair.f)
                {
                  new Chair();
                  new String();
               }
           }
     }
      

  4.   

    看了楼上的回答,我似乎懂了一点。但还有一点:在楼上的机子当产生了2462个Chair对象,i的值就等于47了,它不是等于created的吗?
      

  5.   

    啊, 是我没有说清楚. 
    应该是在我的机器上创建了2462个 Chair对象后, 垃圾回收器决定应该对第47个Chair对象回收, 这时候第47个Chair的finalize()方法被调用. 注意只有这个对象中的i等于47, 因为i是instance field. 所有创建的Chair对象中的 created是相等的,因为 created 是静态变量.
      

  6.   

    class Chair{
       static boolean gcrun=false;
       static boolean f=false;
       static int created=0;
       static int finalized=0;
       int i;
       Chair(){
           i=++created;
           if (created==47)
               System.out.println("Created 47");
        }   public void finalize(){
          if(!gcrun){
               //The first time finalize()is called:
               gcrun=true;
               System.out.println("Beginning to finalize after"+created+"Chairs have been created");
          }
         //如果我这里使用i,也就是书中的。会出现死循环。而当我使用finalized是很正常。
         if(i==47)
            {
                  System.out.println("Finalizing Chair#47,"+created+"Chair have been created");
                  f=true;
            }
        finalized++;}
    }
    public class Garbage
      {
      public static void main(String args[])
            {
                while(!Chair.f){
                  new Chair();
                  new String();
               }
      }
     }
      

  7.   

    C:\j>java  Garbage
    Created 47
    Beginning to finalize after3538Chairs have been created
    Finalizing Chair#47,3538Chair have been created
      

  8.   

    to caiyanying732 (caiyanying732) :AndrewCSDN()说得不是很明确,有些也说得不对!解答有几点:第一: 
      caiyanying732 (caiyanying732) 你贴上的代码中有错误:
     
      a:类Chair的{}少了一个
      b:System.out.println("Finalizing Chair#47,"+"created+"Chair have been created");这句多了个双引号.
      正确的应该是 System.out.println("Finalizing Chair#47,"+created+"Chair have been created");
    第二:
       如AndrewCSDN()所说,垃圾回收器是自己来决定什么时候来回收垃圾的,而垃圾收集是一个独立的低优先级的线程,你可以调用实例的gc()方法来激活垃圾收集.然而,你不能预言,或者说保证垃圾收集会立即开始.  你可以运行垃圾收集器的方法,但不能保证垃圾收集会立即发生.  也可以在运行时用java -noasyncgc来关掉应用程序中的垃圾收集器
      但如果我们关掉垃圾收集,几乎可以肯定程序会由于内存用尽而失败.第三:
       如  AndrewCSDN()所说"不同的 JDK 版本的Java 虚拟机运行同一个这样的程序也会有不同的结果",在我的机器上结果是2788个对象.
      但不是AndrewCSDN()所说那样"在创建2462个Chair对象后,i就等于47了"  正确的是(以我的机器为实例,因为我运行过上百遍,结果一样都是创建2788个Chair对象)
      :当机器创建2788个对象时,虚拟机开始调用垃圾收集,从而调用创建的第一个Chair的finalize()方法,显示"Beginning to finalize after 2788Chairs have been created"这一句,但第一个析构方法的i是1,不会运行
    if(i==47)
           {
                  System.out.println("Finalizing Chair#47, "+created+"Chair have been created");
         f=true;
           }   里面的东西,当收集器进行到第47个对象时,i=47,就运行了if(i==47)判断语句里面的东西了.从而显示:"Finalizing Chair#47, 2788Chair have been created"这一句.
    第四:  因为收集器是作为独立的线程进行的,所以在我机器上(JDK1.4.0_02)是分配CPU的时间片给垃圾收集器.所以从第1个Chair对象到第47个Chair对象一直运行垃圾收集,没有再做
    while(!Chair.f)
    {  new Chair();
       new String();
    }
    的判断运行,所以直到第47个Chair对象时f已经是true了.再由CPU分时间片给主线程做while判断时,因为条件已经变成了假,所以跳出while()循环.程序结束!这个程序不会死循环的,检查一下你的程序,有没有我说的错误,和运行时候等等,因为不同版的虚拟机会不会执行垃圾收集器!
    还有什么不明白,尽管说出来!我有什么不对地方也请指出!!祝好!
      

  9.   

    多谢你们能回答我的问题,还帮我指出毛病。但还有一点不明白的:
    to lionlxz
    当机器创建2788个对象时,虚拟机开始调用垃圾收集,从而调用创建的第一个Chair的finalize()方法,显示"Beginning to finalize after 2788Chairs have been created"这一句,但第一个析构方法的i是1,不会运行      //这里为什么是i=1,i的值不是等于created的吗?
      

  10.   

    嗯, 我已经更正了我的说法. ;)
    "//这里为什么是i=1,i的值不是等于created的吗"
    你创建了2788个Chair对象后, 每个Chiar对象里的i都是不同的(从0到2787),因为i是instance field. 而created 是 static variable静态变量,所有的Chiar对象最后都有一个相等的created 值 2787, (但是运行过程中created 的值是递增的,所以i才会有不同的值)