這篇文章給大家介紹Reference方法如何在Java項(xiàng)目中使用,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
十載的棲霞網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷(xiāo)的優(yōu)勢(shì)是能夠根據(jù)用戶(hù)設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整棲霞建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“棲霞網(wǎng)站設(shè)計(jì)”,“棲霞網(wǎng)站推廣”以來(lái),每個(gè)客戶(hù)項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
Java Reference詳解
在 jdk 1.2 及其以后,引入了強(qiáng)引用、軟引用、弱引用、虛引用這四個(gè)概念。網(wǎng)上很多關(guān)于這四個(gè)概念的解釋?zhuān)蠖嗍歉拍钚缘姆悍憾?,今天我結(jié)合著代碼分析了一下,首先我們先來(lái)看定義與大概解釋?zhuān)ㄒ妙?lèi)型在包 Java.lang.ref 里)。
1、強(qiáng)引用(StrongReference)
強(qiáng)引用不會(huì)被GC回收,并且在java.lang.ref里也沒(méi)有實(shí)際的對(duì)應(yīng)類(lèi)型。舉個(gè)例子來(lái)說(shuō):
Object obj = new Object();
這里的obj引用便是一個(gè)強(qiáng)引用,不會(huì)被GC回收。
2、軟引用(SoftReference)
軟引用在JVM報(bào)告內(nèi)存不足的時(shí)候才會(huì)被GC回收,否則不會(huì)回收,正是由于這種特性軟引用在caching和pooling中用處廣泛。軟引用的用法:
Object obj = new Object(); SoftReference
3、弱引用(WeakReference)
當(dāng)GC一但發(fā)現(xiàn)了弱引用對(duì)象,將會(huì)釋放WeakReference所引用的對(duì)象。弱引用使用方法與軟引用類(lèi)似,但回收策略不同。
4、虛引用(PhantomReference)
當(dāng)GC一但發(fā)現(xiàn)了虛引用對(duì)象,將會(huì)將PhantomReference對(duì)象插入ReferenceQueue隊(duì)列,而此時(shí)PhantomReference所指向的對(duì)象并沒(méi)有被GC回收,而是要等到ReferenceQueue被你真正的處理后才會(huì)被回收。虛引用的用法:
Object obj = new Object(); ReferenceQueue
看了簡(jiǎn)單的定義之后,我們結(jié)合著代碼來(lái)測(cè)試一下,強(qiáng)引用就不用說(shuō)了,軟引用的描述也很清楚,關(guān)鍵是 “弱引用” 與 “虛引用”。
弱引用:
public static void main(String[] args) throws InterruptedException { Object obj = new Object(); ReferenceQueuerefQueue = new ReferenceQueue (); WeakReference weakRef = new WeakReference (obj, refQueue); System.out.println(weakRef.get()); System.out.println(refQueue.poll()); obj = null; System.gc(); System.out.println(weakRef.get()); System.out.println(refQueue.poll()); }
由于System.gc()是告訴JVM這是一個(gè)執(zhí)行GC的好時(shí)機(jī),但具體執(zhí)不執(zhí)行由JVM決定,因此當(dāng)JVM決定執(zhí)行GC,得到的結(jié)果便是(事實(shí)上這段代碼一般都會(huì)執(zhí)行GC):
java.lang.Object@de6ced null null java.lang.ref.WeakReference@1fb8ee3
從執(zhí)行結(jié)果得知,通過(guò)調(diào)用weakRef.get()我們得到了obj對(duì)象,由于沒(méi)有執(zhí)行GC,因此refQueue.poll()返回的null,當(dāng)我們把obj = null;此時(shí)沒(méi)有引用指向堆中的obj對(duì)象了,這里JVM執(zhí)行了一次GC,我們通過(guò)weakRef.get()發(fā)現(xiàn)返回了null,而refQueue.poll()返回了WeakReference對(duì)象,因此JVM在對(duì)obj進(jìn)行了回收之后,才將weakRef插入到refQueue隊(duì)列中。
虛引用:
public static void main(String[] args) throws InterruptedException { Object obj = new Object(); ReferenceQueuerefQueue = new ReferenceQueue (); PhantomReference phanRef = new PhantomReference (obj, refQueue); System.out.println(phanRef.get()); System.out.println(refQueue.poll()); obj = null; System.gc(); System.out.println(phanRef.get()); System.out.println(refQueue.poll()); }
同樣,當(dāng)JVM執(zhí)行了GC,得到的結(jié)果便是:
null null null java.lang.ref.PhantomReference@1fb8ee3
從執(zhí)行結(jié)果得知,我們先前說(shuō)的沒(méi)有錯(cuò),phanRef.get()不管在什么情況下,都會(huì)返回null,而當(dāng)JVM執(zhí)行GC發(fā)現(xiàn)虛引用之后,JVM并沒(méi)有回收obj,而是將PhantomReference對(duì)象插入到對(duì)應(yīng)的虛引用隊(duì)列refQueue中,當(dāng)調(diào)用refQueue.poll()返回PhantomReference對(duì)象時(shí),poll方法會(huì)先把PhantomReference的持有隊(duì)列queue(ReferenceQueue<? super T>)置為NULL,NULL對(duì)象繼承自ReferenceQueue,將enqueue(Reference paramReference)方法覆蓋為return false,而此時(shí)obj再次被GC發(fā)現(xiàn)時(shí),JVM再將PhantomReference插入到NULL隊(duì)列中便會(huì)插入失敗返回false,此時(shí)GC便會(huì)回收obj。事實(shí)上通過(guò)這段代碼我們也的卻看不出來(lái)obj是否被回收,但通過(guò) PhantomReference 的javadoc注釋中有一句是這樣寫(xiě)的:
Once the garbage collector decides that an object obj is phantom-reachable, it is being enqueued on the corresponding queue, but its referent is not cleared. That is, the reference queue of the phantom reference must explicitly be processed by some application code.
翻譯一下(這句話(huà)很簡(jiǎn)單,我相信很多人應(yīng)該也看得懂):
一旦GC決定一個(gè)“obj”是虛可達(dá)的,它(指PhantomReference)將會(huì)被入隊(duì)到對(duì)應(yīng)的隊(duì)列,但是它的指代并沒(méi)有被清除。也就是說(shuō),虛引用的引用隊(duì)列一定要明確地被一些應(yīng)用程序代碼所處理。
弱引用與虛引用的用處
軟引用很明顯可以用來(lái)制作caching和pooling,而弱引用與虛引用呢?其實(shí)用處也很大,首先我們來(lái)看看弱引用,舉個(gè)例子:
class Registry { private Set registeredObjects = new HashSet(); public void register(Object object) { registeredObjects.add( object ); } }
所有我添加進(jìn) registeredObjects 中的object永遠(yuǎn)不會(huì)被GC回收,因?yàn)檫@里有個(gè)強(qiáng)引用保存在registeredObjects里,另一方面如果我把代碼改為如下:
class Registry { private Set registeredObjects = new HashSet(); public void register(Object object) { registeredObjects.add( new WeakReference(object) ); } }
現(xiàn)在如果GC想要回收registeredObjects中的object,便能夠?qū)崿F(xiàn)了,同樣在使用HashMap如果想實(shí)現(xiàn)如上的效果,一種更好的實(shí)現(xiàn)是使用WeakHashMap。
而虛引用呢?我們先來(lái)看看javadoc的部分說(shuō)明:
Phantom references are useful for implementing cleanup operations that are necessary before an object gets garbage-collected. They are sometimes more flexible than the finalize() method.
翻譯一下:
虛引用在實(shí)現(xiàn)一個(gè)對(duì)象被回收之前必須做清理操作是很有用的。有時(shí)候,他們比f(wàn)inalize()方法更靈活。
很明顯的,虛引用可以用來(lái)做對(duì)象被回收之前的清理工作。
關(guān)于Reference方法如何在Java項(xiàng)目中使用就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。