一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - 詳解java中finalize的實現(xiàn)與相應(yīng)的執(zhí)行過程

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

2020-06-14 11:47i flym JAVA教程

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

FinalReference引用

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

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

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

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

Finalizer#register方法

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

?
1
2
3
4
/* Invoked by VM */
static void register(Object finalizee) {
 new Finalizer(finalizee);
}

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

?
1
2
3
4
private Finalizer(Object finalizee) {
 super(finalizee, queue);
 add();
}

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

ReferenceQueue

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

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

FinalizerThread線程

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

?
1
2
3
4
5
6
7
8
for (;;) {
 try {
  Finalizer f = (Finalizer)queue.remove();
  f.runFinalizer(jla);
 } catch (InterruptedException x) {
  // ignore and continue
 }
}

而相應(yīng)的runFinalizer如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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中移除.這個方法是保證每個對象的finalize最多只會被調(diào)用一次,即當(dāng)前這次調(diào)用完了.它就會被記相應(yīng)的狀態(tài),即hasBeenFinalized返回為true(其實就是把里面的next指針指向自己.即自己從未finalize中移除,同時也不需要再次調(diào)用finalize了).

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

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

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

finalizer啟動線程

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

?
1
2
3
4
5
6
7
8
9
10
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ā)相應(yīng)的調(diào)用.這里使用的線程組是系統(tǒng)線程組,優(yōu)先級也還算高,被配置為后臺線程.

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

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

總結(jié)

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 全日本爽视频在线 | 国产男女爱视频在线观看 | 国产福利视频一区二区微拍 | 草草影院国产 | 隔壁老王国产在线精品 | 欧美va在线播放免费观看 | 国产免费午夜高清 | 沉香如屑西瓜视频免费观看完整版 | 国产精品永久免费10000 | 欧美va在线播放免费观看 | 福利片福利一区二区三区 | 成人啪精品视频免费网站 | 国产亚洲精品视频中文字幕 | 爱情岛论坛自拍永久入口 | 2019午夜福合集高清完整版 | 给我免费观看的视频在线播放 | 小早川怜子亚洲综合中文字幕 | 国内小情侣一二三区在线视频 | 亚洲国产综合自在线另类 | 青青草亚洲 | 亚洲国产精品一区二区久久 | 美女脱得一二净无内裤全身的照片 | 女教师巨大乳孔中文字幕免费 | 国产成人精品免费视频大全五级 | 欧美式禁忌 | 精品成人一区二区 | 1024国产基地永久免费 | 国产精品99久久久 | 国产精品永久免费自在线观看 | 色999| 四虎私人影院 | 男人躁女人p | 国产99视频精品免费视频7 | 呜嗯啊野战h呻吟男男双性 污小说在线阅读 | 国产草草 | hd在线观看免费高清视频 | 日韩人成免费网站大片 | 成年人在线免费观看视频网站 | 免费看又黄又爽又猛的视频软件- | 天天做天天爽 | 香蕉精品国产高清自在自线 |