最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解java中finalize的實現(xiàn)與相應的執(zhí)行過程

 更新時間:2016年09月11日 08:57:20   作者:i flym  
在常規(guī)的java書籍中,即會描述 object的finalize方法是用于一些特殊的對象在回收之前再做一些掃尾的工作,但是并沒有說明此是如何實現(xiàn)的.本篇從java的角度(不涉及jvm以及c++),有需要的朋友們可以參考借鑒。

FinalReference引用

此類是一個package類型,表示它并不是公開的一部分,繼承自Reference, 即表示也是一種特定的引用類型,因此每個包裝在其中的對象在被回收之前,自己都會放到指定的referqyebceQueue當中.

這個引用對象專門為帶finalize方法的類服務,可以理解為每一個有相應的方法的對象,其都會封裝為一種finalRefernece對象.

因為finalize方法是object定義的,其默認實現(xiàn)為空.那么如果重寫了此方法,那么方法體肯定不為空.即可以通過這一種區(qū)別來.只要finalize方法實現(xiàn)不為空的類,此產生的對象都需要被注冊到finalRefernece中.

這一步可以通過在newInstance的時候,即調用object默認構造方法的時候,就可以進行相應的注冊了.

Finalizer#register方法

主要調用了此方法,就會產生相應的finalizer對象,而finalizer對象是繼承于finalReference的.此方法聲明如下:

/* Invoked by VM */
static void register(Object finalizee) {
 new Finalizer(finalizee);
}

從上面注釋可以看出,此方法會被jvm在特定時期調用.
然后切換到Finalizer的構造方法,如下所示:

private Finalizer(Object finalizee) {
 super(finalizee, queue);
 add();
}

可以看出,相應的引用對象會通過queue進行回調.add的作用在于將所有還未進行finalize方法的對象存起來,在最后System.shutdown時調用.通過Runtime#runFinalizersOnExit進行設置.

ReferenceQueue

此引用隊列會在相應reference對象的內部對象被回收之前放到此隊列中(詳細說明在另一篇關于reference中再說明.),因為只需要從此隊列中拿到相應的對象,那么此對象就肯定是準備被回收的.

那么在回收之前調用相應的finalize方法即可.

FinalizerThread線程

此線程即是從queue里面,不停的獲取數(shù)據(jù),然后調用相應的finalize方法.相應的代碼如下所示:

for (;;) {
 try {
  Finalizer f = (Finalizer)queue.remove();
  f.runFinalizer(jla);
 } catch (InterruptedException x) {
  // ignore and continue
 }
}

而相應的runFinalizer如下所示:

synchronized (this) {
 if (hasBeenFinalized()) return;
 remove();
}
try {
 Object finalizee = this.get();
 if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
  jla.invokeFinalize(finalizee);
 
  /* Clear stack slot containing this variable, to decrease
   the chances of false retention with a conservative GC */
  finalizee = null;
 }
} catch (Throwable x) { }
 
super.clear();

在上面的邏輯當中,首先調用remove將其從未finalize中移除.這個方法是保證每個對象的finalize最多只會被調用一次,即當前這次調用完了.它就會被記相應的狀態(tài),即hasBeenFinalized返回為true(其實就是把里面的next指針指向自己.即自己從未finalize中移除,同時也不需要再次調用finalize了).

接下來就是調用相應的finalize方法,上面的jla.invokeFinalize其實就是調用相應對象的finalize方法. 在這個處理中,首先通過get獲取原始對象.在整個jvm處理中,針對finalizeReference在回收之前默認是不將引用設置為null.因為這里,總是能夠獲取相應的引用對象.

處理完之后,最后調用相應的clear,清除相應的引用.這樣達到最終引用沒有其它對象可引用的效果.

在上面的處理當中,并沒有限定調用finalize的時間.因此,一旦如果某個對象的finalize調用慢,就會影響到整個回收鏈的執(zhí)行,這下就會產生相應的OOM異常了.因此,除非特殊情況,就不要重寫finalize,相應的場景都應該有其它方法可以處理.比如guava中的FinalizableReference.

finalizer啟動線程

在上面的線程,在相應的進程啟動過程中就會被啟動.可以理解為,對象通過調用register(object)觸發(fā)finalizer類的初始化.然后,在靜態(tài)初始化塊當中,就會啟動相應的回收線程.相應的初始化代碼如下所示:

static {
 ThreadGroup tg = Thread.currentThread().getThreadGroup();
 for (ThreadGroup tgn = tg;
   tgn != null;
   tg = tgn, tgn = tg.getParent());
 Thread finalizer = new FinalizerThread(tg);
 finalizer.setPriority(Thread.MAX_PRIORITY - 2);
 finalizer.setDaemon(true);
 finalizer.start();
}

上面的static是靜態(tài)初始化塊,即只要類Finalizer被使用,即會觸發(fā)相應的調用.這里使用的線程組是系統(tǒng)線程組,優(yōu)先級也還算高,被配置為后臺線程.

在使用jstack打印線程時,出現(xiàn)的如圖下所示的線程,即是由這里來啟動的.如下圖所示

 

總結

整個Finalizer即是通過finalReference,由JVM和相應的java類相互配合來協(xié)同工作.并不是全部由jvm實現(xiàn),因此可以認為其也并不是太底層的東西,而是為了實現(xiàn)相應的語義.一切都是正常的java來完成,由jvm配合.了解到整個過程,也是對java本身的運行機制有所了解.

相關文章

  • Eclipse中配置Maven build打包的方法步驟

    Eclipse中配置Maven build打包的方法步驟

    這篇文章主要介紹了Eclipse中配置Maven build打包的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • SptingBoot過濾器Filter的使用詳解

    SptingBoot過濾器Filter的使用詳解

    這篇文章主要介紹了SptingBoot過濾器Filter的使用詳解,Filter屬于Servlet規(guī)范,并不是Spring獨有的,Filter主要用于攔截請求,做一些業(yè)務邏輯操作,然后可以決定請求是否可以繼續(xù)往下分發(fā),落到其他的Filter或者對應的Servlet,需要的朋友可以參考下
    2023-09-09
  • MyBatis連接數(shù)據(jù)庫配置的基本步驟和機制

    MyBatis連接數(shù)據(jù)庫配置的基本步驟和機制

    MyBatis 是一個流行的持久層框架,它通過使用XML或注解的方式將SQL語句、存儲過程和Java方法進行綁定,從而避免了手寫大量的JDBC代碼和手動設置參數(shù)與結果集,本文給大家介紹了MyBatis連接數(shù)據(jù)庫配置的基本步驟和機制,需要的朋友可以參考下
    2024-05-05
  • 如何將二進制文件流轉化為MockMultipartFile文件

    如何將二進制文件流轉化為MockMultipartFile文件

    文章主要介紹了如何使用Spring框架中的MockMultipartFile類來模擬文件上傳,并處理上傳邏輯,包括獲取二進制文件流、創(chuàng)建MockMultipartFile對象、處理上傳邏輯和返回響應,還解釋了MockMultipartFile的功能和二進制文件流的定義
    2025-02-02
  • 一文讀懂Java多線程背后的故事

    一文讀懂Java多線程背后的故事

    Java是一種廣泛使用的編程語言,而多線程是Java程序員必不可少的一部分,Java的多線程支持具有確保數(shù)據(jù)同步、最大化利用CPU資源、并行處理任務等眾多優(yōu)點,本文從實際應用場景出發(fā),為您詳細介紹 Java 多線程的各個方面的實際應用及背景
    2023-06-06
  • 簡單談談Java中String類型的參數(shù)傳遞問題

    簡單談談Java中String類型的參數(shù)傳遞問題

    這篇文章主要介紹了簡單談談Java中String類型的參數(shù)傳遞問題的相關資料,需要的朋友可以參考下
    2015-12-12
  • spring security獲取用戶信息的實現(xiàn)代碼

    spring security獲取用戶信息的實現(xiàn)代碼

    這篇文章主要介紹了spring security獲取用戶信息的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • vue3實現(xiàn)一個todo-list

    vue3實現(xiàn)一個todo-list

    這篇文章主要為大家詳細介紹了基于vuejs實現(xiàn)一個todolist項目,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-08-08
  • 老生常談java數(shù)組中的常見異常

    老生常談java數(shù)組中的常見異常

    數(shù)組是用來存儲一系列數(shù)據(jù),但它往往被認為是一系列相同類型的變量,異常是程序中的一些錯誤,但并不是所有的錯誤都是異常,并且錯誤有時候是可以避免的,接下來讓我們詳細的了解吧
    2022-03-03
  • SpringMVC之異常處理解讀

    SpringMVC之異常處理解讀

    這篇文章主要介紹了SpringMVC之異常處理解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03

最新評論

英德市| 西贡区| 都江堰市| 卢龙县| 溧阳市| 汤阴县| 旬阳县| 虎林市| 北票市| 贵州省| 通江县| 琼海市| 巫山县| 郁南县| 垫江县| 玉山县| 浦江县| 汤原县| 石棉县| 仁化县| 洛阳市| 宣恩县| 霞浦县| 昌乐县| 罗甸县| 黄冈市| 屯门区| 凯里市| 运城市| 寿光市| 大方县| 新竹县| 霍林郭勒市| 龙山县| 永年县| 长岛县| 岳阳县| 白朗县| 新竹县| 秀山| 邳州市|