? 1.Android引用之強引用(StrongReference)。
? ? ? 啥是強引用呼奢?舉個例子宜雀,我們平時new 的對象,就都是強引用握础。如: String s =new String(),這就是一個強引用州袒,那么強引用有啥特點呢?
強引用對象弓候,也就是new 出來的那種郎哭,可以直接訪問目標對象。
強引用對象菇存,任何時候都不會被系統(tǒng)回收夸研,jvm寧愿拋出outofmemory.也不會回收強引用所指向的對象,也就是說強引用會導(dǎo)致我們常說的內(nèi)存溢出,比如:強引用在引用對象null時會導(dǎo)致內(nèi)存泄漏依鸥。這里注意區(qū)分內(nèi)存溢出和內(nèi)存泄露的區(qū)別亥至。
2.Android引用之軟引用(SoftReference).
? ? 什么是軟引用呢? 上代碼:
privatevoidsoftReferenceMethod(){
Stringstr =newString("abc");
SoftReference softReference =newSoftReference<>(str);
str=null;
//調(diào)用gc回收
? ? ? ? System.gc();
Log.e(TAG,"softReferenceMethod:----------- "+softReference);
? ? }
? ? ? 使用軟引用引用的對象只有在程序發(fā)生oom異常前才會回收贱迟,也就是說如果內(nèi)存充足永遠不會被回收姐扮,只有在內(nèi)存不足時才會回收,很好的避免oom衣吠,適合做緩存茶敏。
那么如何回收引用對象為空的SoftReference對象呢?
? ? ? ? 通常情況下缚俏,我們會配合ReferenceQueue一起使用惊搏,如果引用對象被GC回收,那么SoftReference對象會被列入ReferenceQueue忧换。也就是說恬惯,ReferenceQueue中保存的對象是Reference對象,而且是已經(jīng)失去了它所軟引用的對象的Reference對象亚茬,ReferenceQueue中有一個poll方法酪耳。當我們調(diào)用當我們調(diào)用它的poll()方法的時候,如果這個隊列中不是空隊列刹缝,那么將返回隊列前面的那個Reference對象碗暗。那就好說了奖蔓,如果我們知道此SoftReference對象還不為空,我們把她清空不就好了嗎讹堤?
結(jié)果:
3.Android引用之弱引用(WeakReference).
? ? 弱引用–>隨時可能會被垃圾回收器回收,不一定要等到虛擬機內(nèi)存不足時才強制回收
使用:
privatevoidweakReferenceMethod(){
Stringstr =newString("abc");
WeakReference weakReference =newWeakReference(str);
str=null;
//調(diào)用gc回收
? ? System.gc();
Log.e(TAG,"softReferenceMethod:----------- "+str);
}
實戰(zhàn): 大家在項目中都經(jīng)常使用Handler吧厨疙,我們今天就用WeakReference來優(yōu)化一下洲守,避免內(nèi)存泄漏。代碼如下:
? ? ? ? 先普及一下:當一個android主線程被創(chuàng)建的時候沾凄,同時會有一個Looper對象被創(chuàng)建梗醇,而這個Looper對象會實現(xiàn)一個MessageQueue(消息隊列),當我們創(chuàng)建一個handler對象時撒蟀,就是從這個消息隊列中放入和取出消息叙谨,每當我們通過handler將一個msg放入消息隊列時,這個msg就會持有一個handler對象的引用保屯。
? ? ? 之所以內(nèi)存泄漏手负,大多是因為非靜態(tài)內(nèi)部類或匿名內(nèi)部類,默認持有外部類的引用姑尺,也就是我們的Handller默認持有MainActivity的引用竟终。那如果activity被finish.這個msg在被取出來之前,這msg會繼續(xù)存活切蟋,但是這個msg持有handler的引用统捶,而handler在Activity中創(chuàng)建,會持有Activity的引用柄粹,因而當Activity結(jié)束后喘鸟,Activity對象并不能夠被gc回收,因而出現(xiàn)內(nèi)存泄漏驻右。但靜態(tài)內(nèi)部類不會持有外部類的引用什黑。所以我們把MyHandller定義為靜態(tài)內(nèi)部類避免引用Activity,但這樣的問題是:之前可以直接使用Activity中的方法,現(xiàn)在不持有外部Activity的引用堪夭,也就沒辦法直接通過方法名調(diào)用了兑凿。看代碼茵瘾,我們是這樣解決的:
? MyHandler myHandler;
? ? WeakReference mWeakReference;
@Override
protectedvoidonCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
//softReferenceMethod();
//weakReferenceMethod();
//初始化操作
mWeakReference=newWeakReference(MainActivity.this);
myHandler=newMyHandler(mWeakReference);
myHandler.sendEmptyMessage(0x111);
? ? }
@Override
protectedvoidonDestroy(){
super.onDestroy();
//為了保險起見礼华,清空所有消息隊列
myHandler.removeCallbacksAndMessages(null);
mWeakReference=null;
? ? }
Handler部分代碼:
privatestaticclassMyHandlerextendsHandler{
? ? ? ? MainActivity mainActivity;
publicMyHandler(WeakReference mainActivityWeakReference){
//通過有參構(gòu)造獲取弱引用對象,進而獲取引用對象
? ? ? ? ? ? mainActivity=mainActivityWeakReference.get();
? ? ? ? }
@Override
publicvoidhandleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what ){
case0x111:
//執(zhí)行具體Activity中的方法
? ? ? ? ? ? ? ? ? mainActivity.doSomething();
break;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? 那么我們什么時候用軟引用拗秘,什么時候用弱引用呢圣絮,因為弱引用隨時可能被回收,而軟引用當內(nèi)存不足時才考慮被回收雕旨。所以如果你的引用對象用完之后不會再次重復(fù)使用扮匠,存在的時間短捧请,想要提高性能,盡快被回收就考慮使用弱引用棒搜,否則軟引用疹蛉。兩者都能很好的避免oom的產(chǎn)生。
4.Android引用之虛引用(PhantonReference).
?
? ? ? 虛引用是所有引用類型中最弱的一個力麸。一個持有虛引用的對象可款,和沒有引用幾乎是一樣的,隨時都可能被垃圾回收器回收克蚂。當試圖通過虛引用的get()方法取得強引用時闺鲸,總是會失敗。并且埃叭,虛引用必須和引用隊列一起使用摸恍,它的作用在于跟蹤垃圾回收過程。 當垃圾回收器準備回收一個對象時赤屋,如果發(fā)現(xiàn)它還有虛引用立镶,就會在垃圾回收后,銷毀這個對象类早,將這個虛引用加入引用隊列谜慌,開發(fā)中,沒怎么多用過莺奔。
? ? ? 好了欣范,簡單就介紹這么多了。