日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【深入Java虚拟机JVM 09】JVM垃圾回收finalize方法--对象最有一次自我拯救

發布時間:2025/3/20 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深入Java虚拟机JVM 09】JVM垃圾回收finalize方法--对象最有一次自我拯救 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

說明:文章所有內容均摘自《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版)》

?


即使在可達性分析算法中不可達的對象,也并非是“非死不可”的,這時候它們暫時處于“緩刑”階段。

要真正宣告一個對象死亡,至少要經歷兩次標記過程:如果對象在進行可達性分析后發現沒有與GC Roots相連接的引用鏈,那它將會被第一次標記并且進行一次篩選,篩選的條件是此對象是否有必要執行finalize()方法。當對象沒有覆蓋finalize()方法,或者finalize()方法已經被虛擬機調用過,虛擬機將這兩種情況都視為“沒有必要執行”。

?

如果這個對象被判定為有必要執行finalize()方法,那么這個對象將會放置在一個叫做F-Queue的隊列之中,并在稍后由一個由虛擬機自動建立的、低優先級的Finalizer線程去執行它。這里所謂的“執行”是指虛擬機會觸發這個方法,但并不承諾會等待它運行結束,這樣做的原因是,如果一個對象在finalize()方法中執行緩慢,或者發生了死循環(更極端的情況),將很可能會導致F-Queue隊列中其他對象永久處于等待,甚至導致整個內存回收系統崩潰。finalize()方法是對象逃脫死亡命運的最后一次機會,稍后GC將對F-Queue中的對象進行第二次小規模的標記,如果對象要在finalize()中成功拯救自己——只要重新與引用鏈
上的任何一個對象建立關聯即可,譬如把自己(this關鍵字)賦值給某個類變量或者對象的成員變量,那在第二次標記時它將被移除出“即將回收”的集合;如果對象這時候還沒有逃脫,那基本上它就真的被回收了。從代碼清單3-2中我們可以看到一個對象的finalize()被執行,但是它仍然可以存活。

?

/*** 此代碼演示了兩點:* 1.對象可以在被GC時自我拯救。* 2.這種自救的機會只有一次,因為一個對象的finalize()方法最多只會被系統自動調用一次**/ public class FinalizeEscapeGC {public static FinalizeEscapeGC SAVE_HOOK = null;public void isAlive() {System.out.println("yes,i am still alive:)");}@Overrideprotected void finalize() throws Throwable {super.finalize();System.out.println("finalize mehtod executed!");FinalizeEscapeGC.SAVE_HOOK = this;}public static void main(String[] args) throws Throwable {SAVE_HOOK = new FinalizeEscapeGC();//對象第一次成功拯救自己SAVE_HOOK = null;System.gc();//因為finalize方法優先級很低,所以暫停0.5秒以等待它Thread.sleep(500);if (SAVE_HOOK != null){SAVE_HOOK.isAlive();}else{System.out.println("no,i am dead:(");}//下面這段代碼與上面的完全相同,但是這次自救卻失敗了SAVE_HOOK = null;System.gc();//因為finalize方法優先級很低,所以暫停0.5秒以等待它Thread.sleep(500);if (SAVE_HOOK != null){SAVE_HOOK.isAlive();}else{System.out.println("no,i am dead:(");}} }運行結果: finalize mehtod executed! yes,i am still alive:) no,i am dead:(

?

從代碼清單3-2的運行結果可以看出,SAVE_HOOK對象的finalize()方法確實被GC收集器觸發過,并且在被收集前成功逃脫了。

另外一個值得注意的地方是,代碼中有兩段完全一樣的代碼片段,執行結果卻是一次逃脫成功,一次失敗,這是因為任何一個對象的finalize()方法都只會被系統自動調用一次,如果對象面臨下一次回收,它的finalize()方法不會被再次執行,因此第二段代碼的自救行動失敗了。

需要特別說明的是,上面關于對象死亡時finalize()方法的描述可能帶有悲情的藝術色彩,筆者并不鼓勵大家使用這種方法來拯救對象。相反,筆者建議大家盡量避免使用它,因為它不是C/C++中的析構函數,而是Java剛誕生時為了使C/C++程序員更容易接受它所做出的一個妥協。它的運行代價高昂,不確定性大,無法保證各個對象的調用順序。有些教材中描述它適合做“關閉外部資源”之類的工作,這完全是對這個方法用途的一種自我安慰。finalize()能做的所有工作,使用try-finally或者其他方式都可以做得更好、更及時,所以筆者建議大家完全可以忘掉Java語言中有這個方法的存在。

?

?

?

總結

以上是生活随笔為你收集整理的【深入Java虚拟机JVM 09】JVM垃圾回收finalize方法--对象最有一次自我拯救的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。