1. <progress id="vgiqs"><track id="vgiqs"></track></progress>
      2. <dd id="vgiqs"><pre id="vgiqs"></pre></dd><button id="vgiqs"><object id="vgiqs"></object></button>

        <em id="vgiqs"><acronym id="vgiqs"><u id="vgiqs"></u></acronym></em>
        <button id="vgiqs"></button>
      3. <form id="vgiqs"><strike id="vgiqs"><kbd id="vgiqs"></kbd></strike></form>

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

        全國咨詢/投訴熱線:400-618-4000

        finalize的原理和工作缺點是什么?【Java面試題】

        更新時間:2022年06月15日15時42分 來源:傳智教育 瀏覽次數:

        好口碑IT培訓

        finalize是 Object 中的一個方法,如果子類重寫它,垃圾回收時此方法會被調用,可以在其中進行資源釋放和清理工作。其次將資源釋放和清理放在 finalize 方法中非常不好,非常影響性能,嚴重時甚至會引起 OOM,從 Java9 開始就被標注為 @Deprecated,不建議被使用了。

        對 finalize 方法進行處理的核心邏輯位于 java.lang.ref.Finalizer 類中,它包含了名為 unfinalized 的靜態變量(雙向鏈表結構),Finalizer 也可被視為另一種引用對象(地位與軟、弱、虛相當,只是不對外,無法直接使用)。

        當重寫了 finalize 方法的對象,在構造方法調用之時,JVM 都會將其包裝成一個 Finalizer 對象,并加入 unfinalized 鏈表中。

        構造方法調用

        Finalizer 類中還有另一個重要的靜態變量,即 ReferenceQueue 引用隊列,剛開始它是空的。當狗對象可以被當作垃圾回收時,就會把這些狗對象對應的 Finalizer 對象加入此引用隊列

        但此時 Dog 對象還沒法被立刻回收,因為 unfinalized -> Finalizer 這一引用鏈還在引用它嘛,為的是【先別著急回收啊,等我調完 finalize 方法,再回收】

        FinalizerThread 線程會從 ReferenceQueue 中逐一取出每個 Finalizer 對象,把它們從鏈表斷開并真正調用 finallize 方法。

        由于整個 Finalizer 對象已經從 unfinalized 鏈表中斷開,這樣沒誰能引用到它和狗對象,所以下次 gc 時就被回收了。

        finalize 缺點

        無法保證資源釋放:FinalizerThread 是守護線程,代碼很有可能沒來得及執行完,線程就結束了

        無法判斷是否發生錯誤:執行 finalize 方法時,會吞掉任意異常(Throwable)

        內存釋放不及時:重寫了 finalize 方法的對象在第一次被 gc 時,并不能及時釋放它占用的內存,因為要等著 FinalizerThread 調用完 finalize,把它從 unfinalized 隊列移除后,第二次 gc 時才能真正釋放內存

        有的文章提到【Finalizer 線程會和我們的主線程進行競爭,不過由于它的優先級較低,獲取到的CPU時間較少,因此它永遠也趕不上主線程的步伐】這個顯然是錯誤的,FinalizerThread 的優先級較普通線程更高,原因應該是 finalize 串行執行慢等原因綜合導致

        0 分享到:
        和我們在線交談!
        免费99精品国产自在现线,精品精品国产男人的天堂,国语自产精品视频在 视频_主页