• Tags
  •         
  • www.breakyizhan.com
  •    

    在Java中,垃圾收集器块会对对象进行破坏,并且对它们没有任何引用的对象可以进行垃圾回收。以下是垃圾收集的一些重要输出问题。
    预测以下Java程序的输出:

    • 示例1:
      
      public class Test
      {
          public static void main(String[] args) throws InterruptedException
          {
              String str = new String("GeeksForGeeks");
                   
              // making str eligible for gc
              str = null;
                   
              // calling garbage collector
              System.gc();
                   
              // waiting for gc to complete
              Thread.sleep(1000);
           
              System.out.println("end of main");
          }
      
          @Override
          protected void finalize()
          {
              System.out.println("finalize method called");
          }
      }
      

      输出:

      end of main

      说明:我们知道在销毁对象之前,垃圾收集器会在对象上调用finalize()方法。但在这里,诀窍是str是String类对象,而不是Test类。因此,在str上调用String类的finalize()方法(如果在String类中重写)。如果一个类没有覆盖finalize方法,那么默认调用Object类的finalize()方法。

    • 示例2:
      public class Test
      {
          public static void main(String[] args) throws InterruptedException
          {
              Test t = new Test();
                  
              // making t eligible for garbage collection
              t = null;
                  
              // calling garbage collector
              System.gc();
                  
              // waiting for gc to complete
              Thread.sleep(1000);
          
              System.out.println("end main");
          }
      
          @Override
          protected void finalize()
          {
              System.out.println("finalize method called");
              System.out.println(10/0);
          }
          
      }
      

      输出:

      finalize method called
      end main

      说明:
      当垃圾收集器调用对象的finalize()方法时,它会忽略方法中引发的所有异常,程序将正常终止。

    • 示例3:
      public class Test
      {
          static Test t ;
          
          static int count =0;
          
          public static void main(String[] args) throws InterruptedException
          {
              Test t1 = new Test();
                  
              // making t1 eligible for garbage collection
              t1 = null; // line 12
                  
              // calling garbage collector
              System.gc(); // line 15
                  
              // waiting for gc to complete
              Thread.sleep(1000);
          
              // making t eligible for garbage collection,
              t = null; // line 21
                  
              // calling garbage collector
              System.gc(); // line 24
          
              // waiting for gc to complete
              Thread.sleep(1000);
                  
              System.out.println("finalize method called "+count+" times");
              
          }
          
          @Override
          protected void finalize()
          {
              count++;
              
              t = this; // line 38
                  
          }
          
      }
      

      输出:

      finalize method called 1 times

      说明:
      执行第12行后,t1符合垃圾回收条件。因此,当我们在第15行调用垃圾收集器时,垃圾收集器将在销毁之前调用t1上的finalize()方法。但是在finalize方法中,在第38行中,我们再次通过t引用同一个对象,因此在执行第38行之后,该对象不再符合垃圾回收的条件。因此,垃圾收集器不会销毁该对象。

      现在再次在第21行,我们再次使相同的对象有资格进行垃圾收集。在这里,我们可以清除垃圾收集大约一个事实,即它究竟会调用finalize()方法对特定对象的一个时间。因为在这个对象上,已经调用了finalize()方法,所以现在垃圾收集器会在不再调用finalize()方法的情况下销毁它。

    • 示例4:
      public class Test
      {
          public static void main(String[] args)
          {
              // How many objects are eligible for
              // garbage collection after this line?
              m1();  // Line 5
          }
      
          static void m1()
          {
              Test t1 = new Test();
              Test t2 = new Test();
          }
      }
      

      问题:
      执行第5行后有多少对象符合垃圾回收的条件?
      答案:

      2
      

      说明:
      由于t1和t2是m1()方法的本地对象,因此在完成方法执行后它们才有资格进行垃圾回收,除非返回任何方法。

    • 示例5:
      public class Test
      {
          public static void main(String [] args) 
          {
              Test t1 = new Test();
              Test t2 = m1(t1); // line 6
              Test t3 = new Test();
              t2 = t3; // line 8
              
          }
          
          static Test m1(Test temp)
          {
              temp = new Test();
              return temp;
          }
      }
      

      问题:
      执行第8行后有多少对象符合垃圾回收的条件?
      答案:

      1
      

      说明:
      在第8行执行时,唯一没有引用的对象是生成的对象,即第6行的结果。请记住“ Java严格按值传递 ”,因此引用变量t1不受m1的影响( ) 方法。我们可以使用finalize()方法检查它。finalize()方法中的语句“System.out.println(this.hashcode())”打印调用finalize()方法的对象哈希码值,然后将该值与main方法中创建的其他对象哈希码值进行比较。

     
    转载请保留页面地址:https://www.breakyizhan.com/java/4998.html