一葉笑天
          雄關漫道真如鐵, 而今邁步從頭越。 從頭越, 蒼山如海, 殘陽如血。
          posts - 73,comments - 7,trackbacks - 0
                  Finalizer是不可預知的,經常出問題的,而且是不必要的。使用它可能會導致不可預知的行為,性能降低和簡潔問題。C++需要析構函數釋放資源,Java是用垃圾回收器管理對象釋放。Java中一般在finally中是否其他資源。
                  finalizer的一個缺點是:不能保證他們在對象無用的時候立即執行。這就意味著不能在finalizer中做嚴格要求時間的事情。例如不要在finalizer中關閉文件。
                 finalizer的執行只是垃圾回收器算法的一個主要函數。每個JVM實現都會不同。
                 不要依賴finalizer來更新臨界持有狀態。例如不要在finalizer中釋放共享資源的持有鎖。
                 不要受System.gc和System.runFinalizerOnExit的誘惑.它們可能會增加finalizer執行的機會,但是不能保證。System.runFinalizerOnExit和Runtime.runFinalizersOnExit只是保證finalization。
                  使用finalizers會導致性能損失。在我的機器上創建和銷毀一個對象的時間是5.6ns,但是使用finalizer會增加時間到2400ns.
               那么應該如何終止資源,例如文件和線程?如果僅僅是需要顯式的終止方法,那么可以使用InputStream和OutputStream和java.sql.Connection的Close方法。還有就是使用java.util.Timer的Cancel方法,對于java.awt使用Graphics.dispose和Window.dispose.
               一般典型的顯式終止方法是包含在try-finally中來確保結束。例如
          1// try-finally block guarantees execution of termination method
          2Foo foo = new Foo();
          3try {
          4// Do what must be done with foo
          5
          6}
           finally {
          7foo.terminate(); // Explicit termination method
          8}
               四個類來作為顯示終止方法模式的例子:FileInputStream, FileOutputStream, Timer, and Connection。
                使用finalizer的第二個合理對象是native peers。native peer是一個native對象它是通過native方法來代理正常的對象。由于native peer不是正常的對象,垃圾回收器無法知道它和在Java Peer回收的時候回收它。就需要finalizer來完成這個任務,來確保native peer不再持有臨界資源。
                應該注意到,“finalizer chaining”不是自動完成的。如果一個類有一個finalizer,子類復寫了它。子類必須手動調用父類的finalizer。應該包含子類的finalizer在try中,將父類的finalizer放在finally中:
          // Manual finalizer chaining
          @Override protected void finalize() throws Throwable {
          try {
           
          // Finalize subclass state
          }
           finally {
          super.finalize();
          }

          }
          如果子類實現復寫了父類的finalizer,但是忘記了調用,父類的finalizer就不會被調用。
          可以將finalizer放入一個匿名類中。匿名類的單實例叫做finalizer哨,被包含類為每個實例創建一個finalizer哨。
           1// Finalizer Guardian idiom
           2public class Foo {
           3// Sole purpose of this object is to finalize outer Foo object
           4private final Object finalizerGuardian = new Object() {
           5@Override protected void finalize() throws Throwable {
           6 // Finalize outer Foo object
           7}

           8}
          ;
           9 // Remainder omitted
          10}
          包含類存儲了一個私有單一引用在finalizer哨中。注意,Foo類不需要finalizer,因此不用擔心是否子類調用super.finalize.這種技術應該在每個具有finalizer的非final public 類中考慮。
          總結:
          不要使用finalizer,除非為了安全網或者終止非臨界native資源。在那些使用finalizer的極少的實例中,記住要調用super.finalize。如果使用finalize作為安全網,記住從finalizer中輸出無效用法的日志。最后,如果你需要關聯一個finalizer到public非靜態類中,考慮使用finalizer哨,它可以保證調用super.finalize失敗是還是可以finalization。
          In summary, don’t use finalizers except as a safety net or to terminate
          noncritical native resources. In those rare instances where you do use a finalizer,
          remember to invoke super.finalize. If you use a finalizer as a safety net,
          remember to log the invalid usage from the finalizer. Lastly, if you need to
          associate a finalizer with a public, nonfinal class, consider using a finalizer
          guardian, so finalization can take place even if a subclass finalizer fails to invoke
          super.finalize.

          posted on 2008-06-24 16:07 一葉笑天 閱讀(381) 評論(0)  編輯  收藏 所屬分類: JAVA技術
          主站蜘蛛池模板: 安岳县| 东乌珠穆沁旗| 赤城县| 汉中市| 盐城市| 班玛县| 雅安市| 两当县| 玉环县| 饶平县| 峨眉山市| 嵩明县| 乐都县| 威远县| 杂多县| 曲水县| 阿图什市| 宽甸| 荔波县| 义马市| 徐汇区| 乌恰县| 永胜县| 麻城市| 肥西县| 石楼县| 玛纳斯县| 金堂县| 新巴尔虎右旗| 体育| 扶绥县| 专栏| 抚远县| 资中县| 板桥市| 新巴尔虎左旗| 栖霞市| 黔江区| 晴隆县| 会泽县| 肃北|