一葉笑天
          雄關漫道真如鐵, 而今邁步從頭越。 從頭越, 蒼山如海, 殘陽如血。
          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技術
          主站蜘蛛池模板: 禄劝| 方山县| 仁布县| 桂林市| 特克斯县| 乌鲁木齐县| 区。| 高州市| 闽侯县| 武威市| 张家界市| 额济纳旗| 博爱县| 宜良县| 体育| 介休市| 张家界市| 桃源县| 上饶市| 宁波市| 双江| 芷江| 汤原县| 吉隆县| 越西县| 罗田县| 巴彦县| 工布江达县| 崇礼县| 荔浦县| 响水县| 三台县| 滕州市| 涿鹿县| 阜城县| 荣成市| 行唐县| 清水河县| 陵川县| 庆安县| 天峨县|