在java中談?wù)揥eakReferencence。
在java語(yǔ)言中,對(duì)象的引用分為四個(gè)等級(jí), 強(qiáng)引用 、軟引用,弱引用,虛引用。
本文僅對(duì)java中的弱引用進(jìn)行分析,如有出入請(qǐng)多指正。
在研究弱引用之前,首先要討論一個(gè)概念:目標(biāo)可以達(dá)到什么,對(duì)象不能達(dá)到什么。
實(shí)際上很簡(jiǎn)單,我舉個(gè)例子:
現(xiàn)在有以下兩種類型的class A class B,他們兩個(gè)類別的例子是在JVM上生成的。 instance a instance b
有以下關(guān)系類型:
A a = new A();
B b = new B();
生成了兩個(gè)強(qiáng)引用對(duì)象,好吧,那么這個(gè)時(shí)候我就做一些修改:
A a = new A();
B b = new B(a);
在默認(rèn)構(gòu)造函數(shù)中,B需要一個(gè)A的案例作為參數(shù),所以在這個(gè)時(shí)候, A和B產(chǎn)生了依賴性,也可以說(shuō)A和B產(chǎn)生了依賴性,我們?cè)儆靡粡埥咏鼉?nèi)存結(jié)構(gòu)的圖表來(lái)表達(dá):
A是目標(biāo)A的引用,B是對(duì)象B的引用,對(duì)象B也依賴于目標(biāo)A,所以在這個(gè)時(shí)候,我們認(rèn)為目標(biāo)A可以從對(duì)象B到達(dá)。
所以我又改變了代碼。
A a = new A();
B b = new B(a);
a = null;
A對(duì)象引用A是空的,A不再指向目標(biāo)A地址。我們都知道,當(dāng)一個(gè)目標(biāo)不再被其他對(duì)象引用時(shí),它將被GC回收。顯然,A及時(shí)。=null,所以A的目標(biāo)也是不可能被回收的,因?yàn)锽仍然依賴于A,此時(shí),造成內(nèi)存泄漏!
那怎樣避免上述例子中的內(nèi)存泄漏呢?
很簡(jiǎn)單:
A a = new A();
B b = new B(a);
a = null;
b = null;
此時(shí)B目標(biāo)沒有被引用,A目標(biāo)只被B對(duì)象引用。即便如此,GC也可以同時(shí)回收,因?yàn)樗鼈冊(cè)谝粋€(gè)無(wú)法到達(dá)的地區(qū)。
弱點(diǎn)引用來(lái)了!
A a = new A();
WeakReference wr = new WeakReference(a);
//B b = new B(a);
當(dāng) a=null ,這個(gè)時(shí)候A只是被弱引用依賴,所以GC會(huì)馬上回收A的目標(biāo),這就是弱引用的好處!他可以幫助你合理釋放目標(biāo),在你對(duì)對(duì)象結(jié)構(gòu)和拓?fù)洳皇呛芮宄那闆r下造成不必要的內(nèi)存泄漏??!
在java語(yǔ)言中,對(duì)象的引用分為四個(gè)等級(jí), 強(qiáng)引用 、軟引用,弱引用,虛引用。
本文僅對(duì)java中的弱引用進(jìn)行分析,如有出入請(qǐng)多指正。
在研究弱引用之前,首先要討論一個(gè)概念:目標(biāo)可以達(dá)到什么,對(duì)象不能達(dá)到什么。
實(shí)際上很簡(jiǎn)單,我舉個(gè)例子:
現(xiàn)在有以下兩種類型的class A class B,他們兩個(gè)類別的例子是在JVM上生成的。 instance a instance b
有以下關(guān)系類型:
A a = new A();
B b = new B();
生成了兩個(gè)強(qiáng)引用對(duì)象,好吧,那么這個(gè)時(shí)候我就做一些修改:
A a = new A();
B b = new B(a);
在默認(rèn)構(gòu)造函數(shù)中,B需要一個(gè)A的案例作為參數(shù),所以在這個(gè)時(shí)候, A和B產(chǎn)生了依賴性,也可以說(shuō)A和B產(chǎn)生了依賴性,我們?cè)儆靡粡埥咏鼉?nèi)存結(jié)構(gòu)的圖表來(lái)表達(dá):
A是目標(biāo)A的引用,B是對(duì)象B的引用,對(duì)象B也依賴于目標(biāo)A,所以在這個(gè)時(shí)候,我們認(rèn)為目標(biāo)A可以從對(duì)象B到達(dá)。
所以我又改變了代碼。
A a = new A();
B b = new B(a);
a = null;
A對(duì)象引用A是空的,A不再指向目標(biāo)A地址。我們都知道,當(dāng)一個(gè)目標(biāo)不再被其他對(duì)象引用時(shí),它將被GC回收。顯然,A及時(shí)。=null,所以A的目標(biāo)也是不可能被回收的,因?yàn)锽仍然依賴于A,此時(shí),造成內(nèi)存泄漏!
那怎樣避免上述例子中的內(nèi)存泄漏呢?
很簡(jiǎn)單:
A a = new A();
B b = new B(a);
a = null;
b = null;
此時(shí)B目標(biāo)沒有被引用,A目標(biāo)只被B對(duì)象引用。即便如此,GC也可以同時(shí)回收,因?yàn)樗鼈冊(cè)谝粋€(gè)無(wú)法到達(dá)的地區(qū)。
弱點(diǎn)引用來(lái)了!
A a = new A();
WeakReference wr = new WeakReference(a);
//B b = new B(a);
當(dāng) a=null ,這個(gè)時(shí)候A只是被弱引用依賴,所以GC會(huì)馬上回收A的目標(biāo),這就是弱引用的好處!他可以幫助你合理釋放目標(biāo),在你對(duì)對(duì)象結(jié)構(gòu)和拓?fù)洳皇呛芮宄那闆r下造成不必要的內(nèi)存泄漏?。?/p>
本文僅代表作者觀點(diǎn),版權(quán)歸原創(chuàng)者所有,如需轉(zhuǎn)載請(qǐng)?jiān)谖闹凶⒚鱽?lái)源及作者名字。
免責(zé)聲明:本文系轉(zhuǎn)載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權(quán)或非授權(quán)發(fā)布,請(qǐng)及時(shí)與我們聯(lián)系進(jìn)行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com