GC,Reference,Finalize,Dispose

          Posted on 2008-11-18 14:50 英雄 閱讀(663) 評論(0)  編輯  收藏
           

          GC,Reference,Finalize,Dispose

          Java提供了垃圾對象自動回收(GC)機(jī)制,該機(jī)制對堆heap里的對象就其被引用情況進(jìn)行跟蹤判斷,對合適對象進(jìn)行自動回收釋放內(nèi)存。按java規(guī)范,對象分如下引用情況:

          • An object is strongly reachable if it can be reached by some thread without traversing any reference objects. A newly-created object is strongly reachable by the thread that created it.
          • An object is softly reachable if it is not strongly reachable but can be reached by traversing a soft reference.
          • An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference. When the weak references to a weakly-reachable object are cleared, the object becomes eligible for finalization.
          • An object is phantom reachable if it is neither strongly, softly, nor weakly reachable, it has been finalized, and some phantom reference refers to it.
          • Finally, an object is unreachable, and therefore eligible for reclamation, when it is not reachable in any of the above ways.

          根據(jù)引用情況不同,GC處理過程也不同。

          當(dāng)一個對象實(shí)例不被強(qiáng)引用strongly reachable時,GC的某次運(yùn)行就有可能掃描到該對象。這時GC會檢查該對象是否softreference reachable,如果是,則盡可能放它一馬,一笑而過,但如果放過去就會引起out of memory error,則就要處理該對象。處理過程首先要檢查是否實(shí)現(xiàn)了finalize方法的對象,如果是則標(biāo)記finalizable,并導(dǎo)致Finalizer系統(tǒng)線程(setDaemon(true)Thread.MAX_PRIORITY - 2)在后續(xù)巡檢中對此對象調(diào)用finalize方法。執(zhí)行完finalize方法后如果在此后某次的GC運(yùn)行中再次被發(fā)現(xiàn)softreference reachable,則此時導(dǎo)致clear softreference,并釋放內(nèi)存,最后歸到softreference-queue中。

          如果本對象沒有實(shí)現(xiàn)finalize方法,則GC省去其對應(yīng)處理環(huán)節(jié)。

          此過程同樣適用于weakreference reachable,所不同的是GC將不會盡可能放過該對象。

          對于PhantomReference reachable,情況不同之處在于PhantomReference reachable定義在finalize已經(jīng)執(zhí)行結(jié)束后的GC的某次運(yùn)行時,這個時候,它不去PhantomReference clear,也不釋放內(nèi)存,而是直接歸到PhantomReference-queue中,此后需要應(yīng)用程序自行clear才能釋放,這也是PhantomReference一定要求queue的原因。

          基于此GC機(jī)制,對“實(shí)現(xiàn)當(dāng)不使用某對象時釋放其附屬資源”這樣的需求,java提供兩種實(shí)現(xiàn)方式。

          Finalize方式就是指Object class的那個Finalize方法,可以被任何class進(jìn)行override來實(shí)現(xiàn)釋放對應(yīng)附屬資源。由于歷史原因,執(zhí)行該finalize方法的Finalizer線程保留為一個低優(yōu)先級線程,因此導(dǎo)致獲得巡檢機(jī)會從而進(jìn)行資源釋放將不是十分及時;另外,java規(guī)范允許在finalize方法中再次使該對象恢復(fù)強(qiáng)引用,因而GC總是在執(zhí)行finalize后的再次運(yùn)行中才考慮釋放該對象的內(nèi)存,如果該對象本身占用內(nèi)存比較大,這樣同樣導(dǎo)致整體資源釋放將不是十分及時。最后,如果一個class實(shí)現(xiàn)了finalize方法,不僅如上所述釋放其實(shí)例時比較占用機(jī)器資源,建立實(shí)例的過程也將因要通過必須的finalize方法檢測及底層register而占用額外的資源。為此,java提供了Dispose模式可以用來替代finalize模式。

          Dispose方式的實(shí)現(xiàn)就不在class里實(shí)現(xiàn)finalize方法了。在jre中,已經(jīng)為java2D的支持實(shí)現(xiàn)了一個Disposer用來幫助釋放對象附用的圖形資源,下面以此為例說明Dispose方式。

          sun.java2d.Dispose隨著類加載初始化構(gòu)建一個Java2D Disposer線程(setDaemon(true)Thread.MAX_PRIORITY),同時該類對外提供public static addRecord(Object target, DisposerRecord rec)用來建立對指定targetweakreference PhantomReference(系統(tǒng)屬sun.java2d.reftype指定)監(jiān)測。當(dāng)指定對象target失去強(qiáng)引用而成為weakreferencePhantomReference reachable時,會被GC及時置入reference-queue中,同時被高優(yōu)先級的本Java2D Disposer線程及時監(jiān)測到,然后本線程會去從reference-queue中拿到此reference,并通過內(nèi)部映射表hashtable找到當(dāng)初addRecord時傳入的DisposerRecord,并調(diào)用其dispose()。所以在該dispose方法中實(shí)現(xiàn)釋放附屬資源的邏輯就可以了。


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 邓州市| 江安县| 抚松县| 德化县| 弋阳县| 临沂市| 紫金县| 昭觉县| 棋牌| 辽阳县| 灯塔市| 青阳县| 昌乐县| 江西省| 绩溪县| 白山市| 军事| 志丹县| 井研县| 樟树市| 交口县| 弥渡县| 溧阳市| 汾阳市| 错那县| 辽宁省| 通辽市| 兴安县| 麟游县| 唐山市| 扶绥县| 镇宁| 桦南县| 镇平县| 日喀则市| 大理市| 临夏县| 丁青县| 昂仁县| 忻城县| 越西县|