Java中一次對象的自我拯救探究

編者:明明如月

《深入理解java虛擬機》第二版 67頁,一次對象自我拯救這個例子很不錯,在這裡分享出來。

並且從源碼角度進行分析。

Java中一次對象的自我拯救探究

代碼如下:

Java中一次對象的自我拯救探究

Java中一次對象的自我拯救探究

運行結果

Java中一次對象的自我拯救探究

我們可以看出,SAVE_HOOK對象的finalize()方法確實被GC回收器出發過,並且在被收集前成功逃脫。

我們先研究一下垃圾回收方法

Java中一次對象的自我拯救探究

此方法調用垃圾回收器,回收被遺棄的對象。並且和Runtime.getRuntime().gc()這個方法等價,因為從源碼中我們看出其實就是直接調用了那個方法

Java中一次對象的自我拯救探究

我們看到這個是原生的方法,哪怕gc方法沒有被顯式調用,虛擬機根據需要自動執行垃圾回收線程。

我們再看看Object對象的finalize()方法:

Java中一次對象的自我拯救探究

Java中一次對象的自我拯救探究

主要幾點:

  1. 當垃圾回收器斷定一個對象不再被引用,該對象的該方法就會被垃圾回收器調用。

  2. 子類可以重寫finalize方法來釋放系統資源或者執行一些清理的操作。

  3. finalize方法可以執行任何操作,包括再使得該對象可用(拯救該對象)。

  4. Java編程語言並不保證哪一個線程來調用某個對象的finalize方法。

  5. finalize方法只會被Java虛擬機調用一次。


主方法中,上半段和下半段代碼相同,可是一次逃脫成功,一次逃脫失敗,是因為任何一個對象的finalize()方法只會被系統自動調用一次,如果對象再次面臨回收,他的finalize()方法不會再次被執行,第二段代碼的自救行動就失敗了(因為再次調用gc來執行垃圾回收,該對象的finalize方法不會再次被執行)。

書中作者不鼓勵使用該方法來拯救對象。

作者表示有的教材鼓勵採用這種方式在finalize()方法中“關閉外部資源”之類的工作。finalize()能做的工作通過try-finally或者其他方式也可以做得更好、更及時,所以請淡忘這個方法。

大家在編程過程中,尤其在學習虛擬機的一些知識時,多去查看源碼。


分享到:


相關文章: