教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

finalize的原理和工作缺點(diǎn)是什么?【Java面試題】

更新時(shí)間:2022年06月15日15時(shí)42分 來(lái)源:傳智教育 瀏覽次數(shù):

好口碑IT培訓(xùn)

finalize是 Object 中的一個(gè)方法,如果子類重寫它,垃圾回收時(shí)此方法會(huì)被調(diào)用,可以在其中進(jìn)行資源釋放和清理工作。其次將資源釋放和清理放在 finalize 方法中非常不好,非常影響性能,嚴(yán)重時(shí)甚至?xí)?OOM,從 Java9 開(kāi)始就被標(biāo)注為 @Deprecated,不建議被使用了。

對(duì) finalize 方法進(jìn)行處理的核心邏輯位于 java.lang.ref.Finalizer 類中,它包含了名為 unfinalized 的靜態(tài)變量(雙向鏈表結(jié)構(gòu)),F(xiàn)inalizer 也可被視為另一種引用對(duì)象(地位與軟、弱、虛相當(dāng),只是不對(duì)外,無(wú)法直接使用)。

當(dāng)重寫了 finalize 方法的對(duì)象,在構(gòu)造方法調(diào)用之時(shí),JVM 都會(huì)將其包裝成一個(gè) Finalizer 對(duì)象,并加入 unfinalized 鏈表中。

構(gòu)造方法調(diào)用

Finalizer 類中還有另一個(gè)重要的靜態(tài)變量,即 ReferenceQueue 引用隊(duì)列,剛開(kāi)始它是空的。當(dāng)狗對(duì)象可以被當(dāng)作垃圾回收時(shí),就會(huì)把這些狗對(duì)象對(duì)應(yīng)的 Finalizer 對(duì)象加入此引用隊(duì)列

但此時(shí) Dog 對(duì)象還沒(méi)法被立刻回收,因?yàn)?unfinalized -> Finalizer 這一引用鏈還在引用它嘛,為的是【先別著急回收啊,等我調(diào)完 finalize 方法,再回收】

FinalizerThread 線程會(huì)從 ReferenceQueue 中逐一取出每個(gè) Finalizer 對(duì)象,把它們從鏈表斷開(kāi)并真正調(diào)用 finallize 方法。

由于整個(gè) Finalizer 對(duì)象已經(jīng)從 unfinalized 鏈表中斷開(kāi),這樣沒(méi)誰(shuí)能引用到它和狗對(duì)象,所以下次 gc 時(shí)就被回收了。

finalize 缺點(diǎn)

無(wú)法保證資源釋放:FinalizerThread 是守護(hù)線程,代碼很有可能沒(méi)來(lái)得及執(zhí)行完,線程就結(jié)束了

無(wú)法判斷是否發(fā)生錯(cuò)誤:執(zhí)行 finalize 方法時(shí),會(huì)吞掉任意異常(Throwable)

內(nèi)存釋放不及時(shí):重寫了 finalize 方法的對(duì)象在第一次被 gc 時(shí),并不能及時(shí)釋放它占用的內(nèi)存,因?yàn)橐戎?FinalizerThread 調(diào)用完 finalize,把它從 unfinalized 隊(duì)列移除后,第二次 gc 時(shí)才能真正釋放內(nèi)存

有的文章提到【Finalizer 線程會(huì)和我們的主線程進(jìn)行競(jìng)爭(zhēng),不過(guò)由于它的優(yōu)先級(jí)較低,獲取到的CPU時(shí)間較少,因此它永遠(yuǎn)也趕不上主線程的步伐】這個(gè)顯然是錯(cuò)誤的,F(xiàn)inalizerThread 的優(yōu)先級(jí)較普通線程更高,原因應(yīng)該是 finalize 串行執(zhí)行慢等原因綜合導(dǎo)致

0 分享到:
和我們?cè)诰€交談!