《Effective Java 中文版 第2版》學習筆記 第7條:避免使用終結方法

來源:互聯網
上載者:User

標籤:檔案   分布式系統   調用本地   資料庫   測試   應該   線程   保留   分布式   

  在Java中,當一個對象變得不可到達時,記憶體回收行程會回收與該對象相關聯的儲存空間。用try-finally塊來回收其他的非記憶體資源。

 

  終結方法的缺點在於不能保證會被及時地執行。從一個對象變得不可到達開始,到它的終結方法被執行,所花費的這段時間是任意長的。這意味著注重時間的任務不應該由終結方法來完成。例如,用終結方法來關閉已經開啟的檔案是錯誤的,因為開啟檔案的描述符是一種很有限的資源。由於JVM會順延強制終結方法,所以大量的檔案會保留在開啟狀態,當一個程式再不能開啟檔案的時候,它可能會運行失敗。

  及時地執行終結方法是記憶體回收演算法的一個主要功能,這種演算法在不同的JVM實現中會大相徑庭。如果程式依賴於終結方法被執行的時間點,這個程式的行為在不同的JVM中啟動並執行表現可能會截然不同。一個程式在自己測試用的JVM平台上運行得非常好,而在客戶的JVM平台上可能根本無法運行。

 

  Java語言規範不僅不保證終結方法會被及時地執行,而且根本就不保證它們會被執行。當一個程式終止時,某些已經無法訪問的對象上的終結方法可能根本沒有被執行。所以,不應該依賴終結方法來更新重要的持久狀態。例如,依賴終結方法來釋放共用資源(比如資料庫)上的永久鎖,很容易讓整個分布式系統垮掉。

  System.gc和System.runFinalization這兩個方法雖然增加了終結方法被執行的機會,但是不保證一定會執行終結方法。System.runFinalizersOnExit以及其孿生兄弟Runtime.runFinalizersOnExit這兩個方法雖然聲稱保證終結方法被執行,但是都有致命的缺陷,已經被廢棄了。

 

  如果未被捕獲的異常在終結過程中被拋出來,這種異常會被忽略,並且該對象的終結過程也會終止。換言之,如果異常發生在終結方法之中,它不會使線程終止,也不會列印出棧軌跡(Stack Trace),甚至不會列印警告。

 

  使用終結方法會有嚴重的(Severe)效能損失。也就是說,增加終結方法會使處理速度變慢。

 

  如果類的對象中封裝的資源(例如檔案或者線程)需要終止,只需提供一個顯式的終止方法,並要求該類的用戶端在每個執行個體不再有用時調用這個方法。其中,顯式的終止方法必須在一個私人域中記錄下“該對象已經不再有效”。如果終止方法是在對象已經終止之後被調用,其他的方法必須檢查這個域,並拋出IllegalStateException異常。顯式的終結方法通常與try-finally結構結合起來使用,確保及時終止。在finally子句內部調用顯式的終止方法,保證即使在使用對象時拋出異常,該終止方法也會執行。

  

  終結方法有兩種合法用途。

  第一種用途:當對象的所有者忘記調用顯式終止方法時,終結方法可以充當“安全網(safety net)”,遲一點釋放關鍵資源總比永遠不釋放要好。

  第二種用途:本地對等體(native peer)是一個本機物件(native object),普通對象通過本地方法(native method)委託給一個本機物件。因為本地對等體不是一個普通對象,所以記憶體回收行程不會知道它,當它的Java對等體被回收時,它不會被回收。在本地對等體不擁有關鍵資源的前提下,終結方法會回收它。如果本地對等體擁有必須被及時終止的資源,該類就應該具有一個顯式的終止方法。終止方法可以是本地方法,也可以調用本地方法。

 

  “終結方法鏈(finalizer chaining)”不會被自動執行。如果類(不是Object)有終結方法,並且子類覆蓋了終結方法,子類的終結方法就必須手工調用超類的終結方法。在一個try塊中終結子類,並在相應的finally塊中調用超類的終結方法。保證即使子類的終結過程拋出異常,超類的終結方法也會得到執行。

1 @Override2 protected void finalize() throws Throwable {3     try {4         ... // 終結子類狀態5     } finally {6         super.finalize(); // 終結父類狀態7     }8 }

 

  總之,除非是作為安全網,或者是為了終止非關鍵的本地資源,否則請不要使用終結方法。

 

  參考資料

  《Effective Java 中文版 第2版》 P24-27

《Effective Java 中文版 第2版》學習筆記 第7條:避免使用終結方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.