首頁 > Java > java教程 > 主體

Java實作禁止使用finalize的方法介紹

黄舟
發布: 2017-10-14 09:37:55
原創
1213 人瀏覽過

這篇文章主要介紹了Java禁止使用finalize方法,需要的朋友可以參考下

什麼是finalize方法

finalize ()方法被定義在Java.lang.Object類別中,表示所有的類別都可以重載這個方法。 java垃圾回收器只之道釋放那些經由new分配的內存,所以如果你的物件並非透過new獲得的內存,那麼垃圾回收器就不知道如何釋放該物件的內存了。

為了回應這種情況,java允許在類別中重載java.lang.Object類別中的finalize()方法。

它的工作原理:一旦垃圾回收器準備好釋放物件佔用的儲存空間,將首先呼叫其finalize()方法,並且在下一次垃圾回收動作發生時,才會真正回收物件佔用的內存。

finalize函數的呼叫機制

java虛擬機規格並沒有硬性規定垃圾回收該不該搞,以及該如何搞。所以這裡提到的呼叫機制不能保證適合所有jvm。

何時被呼叫?

  finalize啥時候才會被呼叫捏?一般來說,要等到JVM開始進行垃圾回收的時候,它才有可能被呼叫。而JVM進行垃圾回收的時間點是非常不確定的,依賴各種運行時的環境因素。正是由於finalize函數呼叫時間點的不確定,導致了後面提到的某些缺點。

誰來呼叫?

  常見的JVM會透過GC的垃圾回收執行緒來進行finalize函數的呼叫。由於垃圾回收線程比較重要(人家好歹也是JVM的一個組成部分嘛),為了防止finalize函數拋出的異常影響到垃圾回收線程的運作,垃圾回收線程會在調用每一個finalize函數時進行try catch,如果捕獲到異常,就直接丟棄,然後接著處理下一個失效物件的finalize函數。

為什麼禁止使用finalize()

#1.呼叫時間不確定---有資源浪費的風險

前面已經介紹了呼叫機制。同學們應該認清「finalize的調用時機是很不確定的」這樣一個事實。所以,假如你把某些稀缺資源放到finalize()中釋放,可能會導致該稀缺資源等上很久很久很久以後才被釋放。這可是資源的浪費啊!另外,某些類別物件所攜帶的資源(例如某些JDBC的類別)可能本身就很耗費內存,這些資源的延遲釋放會造成很大的效能問題。

2.可能不會被調用----有資源洩漏的風險

很多同學以為finalize()總是會被調用,其實不然。在某些情況下,finalize()壓根兒不被呼叫。例如在JVM退出的當口,記憶體中那些物件的finalize函數可能就不會被呼叫了。

估計有同學在打「runFinalizersOnExit」的主意,來確保所有的finalize在JVM退出前被呼叫。很可惜也很遺憾,該方法從JDK 1.2開始,就已經被廢棄了。即使該方法不被廢棄,也是有很大的線程安全隱患滴!   

從上述可以看出,一旦你依賴finalize()來幫你釋放資源,那可是很不妙啊(有資源洩漏的危險)!很多時候,資源外洩導致的效能問題更加嚴重,萬萬不可小看。

3.物件可能在finalize函數呼叫時復活

本來,只有當某個物件已經失效(沒有引用),垃圾回收器才會呼叫該對象的finalize函數。但是,萬一碰上某個變態的程式設計師,在finalize()函數內部再把物件自身的引用(也就是this)重新保存在某處,也就相當於把自己復活了(因為這個物件重新有了引用,不再處於失效狀態)。 為了防止發生這種詭異的事情,垃圾回收器只能在每次調用完finalize()之後再次去檢查該物件是否還處於失效狀態。這無形中又增加了JVM的開銷。隨便提一下。由於JDK的文檔中規定了,JVM對於每一個類別物件實例最多只會呼叫一次finalize()。所以,對於那些詐屍的實例,當它們真正死亡時,finalize()反而不會被呼叫了。這看起來是不是很奇怪?

4.要記得自己做異常捕獲

剛才在介紹finalize()呼叫機制時提到,一旦有異常拋出到finalize函數外面,會被垃圾回收線程捕獲並丟棄。也就是說,異常被忽略了(異常被忽略的危害,「這裡」有提到)。為了防止這種事兒,凡是finalize()中有可能拋出異常的程式碼,你都得寫上try catch語句,自己進行捕獲。

5.小心線程安全

由於呼叫finalize()的是垃圾回收線程,和你自己程式碼的線程不是同一個線程;甚至不同物件的finalize()可能會被不同的垃圾回收線程呼叫(例如使用「並行收集器」的時候)。所以,當你在finalize()裡面存取某些資料的時候,還得時時刻刻留心線程安全的問題。

總結

#

以上是Java實作禁止使用finalize的方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板