程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 關於finalize()方法的解釋

關於finalize()方法的解釋

編輯:JAVA編程入門知識

  我在thinking in Java中看見以下一段代碼。
  
  //:Garbage.java
  //Demonstration of the garbage
  //collector and finalization
  
  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");
      }
      protected void finalize(){
          if(!gcrun){
              gcrun=true;
              System.out.println(
                  "Beginning to finalize after"+created+
                  "Chairs have been created");
          }
      if(i==47){
          System.out.println(
              "Finalizing Chair #47,"+
              "Setting flag to stop Chair creation");
          f=true;
      }
      finalized++;
      if(finalized>=created)
          System.out.println(
              "All"+finalized+"finalized");
      }
  }
  
  public class Garbage{
      public static void main(String[] args){
        if(args.length==0){
            System.out.println("Usage: "+
                "java Garbage before  or: "+
                "java Garbage after");
            return;
        }
        while(!Chair.f){
            new Chair();
            new String("To take up space");
        }
        System.out.println(
            "After all chairs have been created: "+
            "total created ="+Chair.created+
            ",total finalized ="+Chair.finalized);
        if(args[0].equals("before")){
            System.out.println("gc():");
            System.gc();
            System.out.println("runFinalization():");
            System.runFinalization();
        }
        System.out.println("bye");
        if(args[0].equals("after"))
            System.runFinalizersOnExit(true);
      }
  }///:-
  
  為什麼執行java Gerbage before
  以後,當所有對象創建完(比如8000個),這時只清除了2000個(不定)
  應該只能創建47個對象啊
  
  分析:
  首先,在一個循環當中創建對象,並且只是創建,而不引用,也就是說這個對象會自動的被系統當作垃圾處理掉。但請注重,finalize()方法並不是馬上就會執行的,執行的時間完全由系統來決定。所以很有可能的情況是已經創建了20000個對象,才開始其中的某一個對象的清除工作(這可能和時間或者系統內容的占用有關)。看finalize()方法中的一段代碼:
      if (!gcrun) {
          gcrun = true;
          System.out.println(
              " Beginning to finalize after" + created + "Chairs have been created at ");
      }
  就會出現這樣的結果:
  Beginning to finalize after 25038 Chairs have been created
  
  這時對象的創建過程仍在繼續(因為已經Finalize的對象還不滿47個,Chair.f還是false)。所以Chair.created會繼續增加。
  直到有47個對象被清除了,Chair.f被置成true了,創建對象的循環才結束。看main方法中的一段代碼:
      System.out.println(
          " After all chairs have been created: "
              + "total created ="
              + Chair.created
              + ",total finalized ="
              + Chair.finalized+" ");
  如上所說,Chair.created是不斷增加的,而在這段代碼執行之前,又會有N個對象被釋放掉了,所以finalized也增加了。
  結果可能是這樣的:
  total created =29096,total finalized =73
  
  其實這一過程和你使用的JVM有很大關系,執行結果可能會很不相同。但有一點是可以肯定的,那就是我們無法確定JVM什麼時候做對象的清除工作(這也是Thinking in java中這段代碼的想要說明的),可能會在這個對象剛剛“無用”的時候就清除掉了,也可能滯後幾秒,甚至永遠不清除。
  
  假如你的開發環境支持跟蹤的話,你可以以STEP的方式運行,你會看到運行結果大不相同。給你看看我的運行結果:
  Created 47
  Beginning to finalize after25038Chairs have been created
  Finalizing Chair #47,Setting flag to stop Chair creation
  After all chairs have been created:
  total created =45993,total finalized =1800
  gc():
  runFinalization():
  bye
  All45993finalized
  
  注重最後一行,因為人為的停頓,JVM有足夠的時間將所有的對象都清除了。
  
  結論:
  不能指望finalize()方法能穩定的工作,尤其不能依靠它來做文件的關閉等操作,由於finalize()的不確定性,往往得不到你想要的結果。事實上我們只需要知道所有無用的對象,JVM會自己清除就夠了。
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved