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

詳解java中finalize的實(shí)現(xiàn)與相應(yīng)的執(zhí)行過(guò)程

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

FinalReference引用

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

這個(gè)引用對(duì)象專(zhuān)門(mén)為帶finalize方法的類(lèi)服務(wù),可以理解為每一個(gè)有相應(yīng)的方法的對(duì)象,其都會(huì)封裝為一種finalRefernece對(duì)象.

因?yàn)閒inalize方法是object定義的,其默認(rèn)實(shí)現(xiàn)為空.那么如果重寫(xiě)了此方法,那么方法體肯定不為空.即可以通過(guò)這一種區(qū)別來(lái).只要finalize方法實(shí)現(xiàn)不為空的類(lèi),此產(chǎn)生的對(duì)象都需要被注冊(cè)到finalRefernece中.

這一步可以通過(guò)在newInstance的時(shí)候,即調(diào)用object默認(rèn)構(gòu)造方法的時(shí)候,就可以進(jìn)行相應(yīng)的注冊(cè)了.

Finalizer#register方法

主要調(diào)用了此方法,就會(huì)產(chǎn)生相應(yīng)的finalizer對(duì)象,而finalizer對(duì)象是繼承于finalReference的.此方法聲明如下:

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

從上面注釋可以看出,此方法會(huì)被jvm在特定時(shí)期調(diào)用.
然后切換到Finalizer的構(gòu)造方法,如下所示:

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

可以看出,相應(yīng)的引用對(duì)象會(huì)通過(guò)queue進(jìn)行回調(diào).add的作用在于將所有還未進(jìn)行finalize方法的對(duì)象存起來(lái),在最后System.shutdown時(shí)調(diào)用.通過(guò)Runtime#runFinalizersOnExit進(jìn)行設(shè)置.

ReferenceQueue

此引用隊(duì)列會(huì)在相應(yīng)reference對(duì)象的內(nèi)部對(duì)象被回收之前放到此隊(duì)列中(詳細(xì)說(shuō)明在另一篇關(guān)于reference中再說(shuō)明.),因?yàn)橹恍枰獜拇岁?duì)列中拿到相應(yīng)的對(duì)象,那么此對(duì)象就肯定是準(zhǔn)備被回收的.

那么在回收之前調(diào)用相應(yīng)的finalize方法即可.

FinalizerThread線程

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

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

而相應(yīng)的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();

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

接下來(lái)就是調(diào)用相應(yīng)的finalize方法,上面的jla.invokeFinalize其實(shí)就是調(diào)用相應(yīng)對(duì)象的finalize方法. 在這個(gè)處理中,首先通過(guò)get獲取原始對(duì)象.在整個(gè)jvm處理中,針對(duì)finalizeReference在回收之前默認(rèn)是不將引用設(shè)置為null.因?yàn)檫@里,總是能夠獲取相應(yīng)的引用對(duì)象.

處理完之后,最后調(diào)用相應(yīng)的clear,清除相應(yīng)的引用.這樣達(dá)到最終引用沒(méi)有其它對(duì)象可引用的效果.

在上面的處理當(dāng)中,并沒(méi)有限定調(diào)用finalize的時(shí)間.因此,一旦如果某個(gè)對(duì)象的finalize調(diào)用慢,就會(huì)影響到整個(gè)回收鏈的執(zhí)行,這下就會(huì)產(chǎn)生相應(yīng)的OOM異常了.因此,除非特殊情況,就不要重寫(xiě)finalize,相應(yīng)的場(chǎng)景都應(yīng)該有其它方法可以處理.比如guava中的FinalizableReference.

finalizer啟動(dòng)線程

在上面的線程,在相應(yīng)的進(jìn)程啟動(dòng)過(guò)程中就會(huì)被啟動(dòng).可以理解為,對(duì)象通過(guò)調(diào)用register(object)觸發(fā)finalizer類(lèi)的初始化.然后,在靜態(tài)初始化塊當(dāng)中,就會(huì)啟動(dòng)相應(yīng)的回收線程.相應(yīng)的初始化代碼如下所示:

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)初始化塊,即只要類(lèi)Finalizer被使用,即會(huì)觸發(fā)相應(yīng)的調(diào)用.這里使用的線程組是系統(tǒng)線程組,優(yōu)先級(jí)也還算高,被配置為后臺(tái)線程.

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

 

總結(jié)

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

相關(guān)文章

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

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

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

    SptingBoot過(guò)濾器Filter的使用詳解

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

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

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

    如何將二進(jìn)制文件流轉(zhuǎn)化為MockMultipartFile文件

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

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

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

    簡(jiǎn)單談?wù)凧ava中String類(lèi)型的參數(shù)傳遞問(wèn)題

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

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

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

    vue3實(shí)現(xiàn)一個(gè)todo-list

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

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

    數(shù)組是用來(lái)存儲(chǔ)一系列數(shù)據(jù),但它往往被認(rèn)為是一系列相同類(lèi)型的變量,異常是程序中的一些錯(cuò)誤,但并不是所有的錯(cuò)誤都是異常,并且錯(cuò)誤有時(shí)候是可以避免的,接下來(lái)讓我們?cè)敿?xì)的了解吧
    2022-03-03
  • SpringMVC之異常處理解讀

    SpringMVC之異常處理解讀

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

最新評(píng)論

博野县| 宕昌县| 伊金霍洛旗| SHOW| 东港市| 汾阳市| 读书| 汉沽区| 兴海县| 西昌市| 东兴市| 邹城市| 湘潭县| 南安市| 乾安县| 两当县| 梅州市| 保靖县| 康平县| 乐至县| 中牟县| 台安县| 什邡市| 伊金霍洛旗| 和顺县| 辰溪县| 微博| 宁津县| 新宾| 林州市| 庆阳市| 诸暨市| 垫江县| 灯塔市| 鹤壁市| 合阳县| 石门县| 罗平县| 洛阳市| 兴安县| 仁怀市|