一香追、引用對象類型定義
????首先怜奖,引用對象在Java定義中有三種類型,從弱到強依次為:軟引用翅阵、弱引用與虛引用歪玲,三種級別也各有所不同(軟引用>弱引用)迁央。本文淺析下軟引用與弱引用。大概的解釋滥崩,軟引用適合應用在需要cache的場景岖圈,一般面向?qū)崿F(xiàn)內(nèi)存敏感的緩存;弱引用則是適用在某些場景為了無法防止被回收的規(guī)范性映射钙皮,它優(yōu)先級最低蜂科,一般與引用隊列聯(lián)合使用。
詳細介紹:
(一)強引用(默認存在)
????強引用短条,是在實際開發(fā)中最為普遍的引用导匣。有時候你開發(fā)的時候,申請一個內(nèi)存空間的時候茸时,就已經(jīng)是強引用了贡定。例如:
Object obj =new Object(); // 強引用
????在強引用中,如果不讓該對象指向為空可都,垃圾回收器絕對不會回收它缓待。除非當出現(xiàn)內(nèi)存空間不足的時候。jvm拋出oom導致程序異常種植的時候渠牲,才會回收具有強引用的對象來解決內(nèi)存空間不足問題旋炒。
Object obj =new Object(); // 強引用
obj = null;//這時候為垃圾回收器回收這個對象,至于什么時候回收签杈,取決于垃圾回收器的算法
(二)軟引用(SoftReference )
????軟引用對象也比較好理解瘫镇,它是一個比較特殊的存在,擁有強引用的屬性答姥,又更加安全汇四。如果有一個對象具有軟引用。在內(nèi)存空間足夠的情況下踢涌,除非內(nèi)存空間接近臨界值通孽、jvm即將拋出oom的時候,垃圾回收器才會將該引用對象進行回收睁壁,避免了系統(tǒng)內(nèi)存溢出的情況背苦。(前提也是對象指向不為空)因此,SoftReference 引用對象非常適合實現(xiàn)內(nèi)存敏感的緩存潘明,例如加載圖片的時候行剂,bitmap緩存機制。
String value = new String(“sy”);
SoftReference sfRefer = new SoftReference (value );
sfRefer .get();//可以獲得引用對象值
(三)弱引用(WeakReference)
????顧名思義钳降,一個具有弱引用的對象厚宰,與軟引用對比來說,前者的生命周期更短。當垃圾回收器掃描到弱引用的對象的時候铲觉,不管內(nèi)存空間是否足夠澈蝙,都會直接被垃圾回收器回收。不過也不用特別擔心撵幽,垃圾回收器是一個優(yōu)先級比較低的現(xiàn)場灯荧,因此不一定很快可以發(fā)現(xiàn)弱引用的對象。
???另外盐杂,google官方是推薦Android開發(fā)者使用WeakReference逗载,而不建議SoftReference 引用,Android環(huán)境下與純Java有所略同链烈。下面待會說明情況厉斟。
String value = new String(“sy”);
WeakReference weakRefer = new WeakReference(value );
System.gc();
weakRefer.get();//null
二、Java環(huán)境與Android環(huán)境對比異同點
下面直接貼一份代碼强衡,同一份代碼擦秽,比較在android環(huán)境下輸出的結(jié)果與Java輸出的結(jié)果:
public static void main(String[] args) throws InterruptedException {
initsoftReference();
initweakReference();
Thread.sleep(2000);
System.gc();
if (softReference.get() == null) {
System.out.println("SoftReference : " + "null");
}else{
System.out.println("SoftReference : " + softReference.get());
}
if (weakReference.get() == null) {
System.out.println("WeakReference : " + "null");
}else{
System.out.println("WeakReference : " + weakReference.get());
}
}
private static void initsoftReference() {
softReference = new SoftReference(value_soft);
value_soft = null;
}
private static void initweakReference() {
weakReference = new WeakReference(value_weak);
value_weak = null;
}
純Java環(huán)境運行情況:
Android環(huán)境運行情況:
????從上面的情況,我們還讓你容易可以觀察Android環(huán)境下與純Java環(huán)境下兩者直接的輸出結(jié)果不同食侮!在Android環(huán)境下WeakReference 與SoftReference 兩者輸出結(jié)果一樣。其實對于手機系統(tǒng)存在多應用目胡,又對于內(nèi)存是比較敏感的锯七,自然對于內(nèi)存釋放會更加嚴格。試想一下誉己,如果眾多對象使用 SoftReference引用眉尸,大部分都是這也是為什么google不建議SoftReference 的原因之一,至于軟引用與弱引用在android環(huán)境中輸出結(jié)果一致巨双,這個筆者也匪夷所思...
三噪猾、實戰(zhàn)應用內(nèi)存優(yōu)化策略避免Handler內(nèi)存泄漏
????前,在日常開發(fā)中筑累,其實對內(nèi)存比較敏感的袱蜡,例如Activity、webView慢宗、bitmap坪蚁、Handler等等,舉例如果我們擁有一個管理Activity的管理類镜沽,即Activity需要暴露在外面敏晤,如果當前其中有一個Activity正在執(zhí)行一個耗時的任務,如果使用強引用缅茉,這一系列過程很吃內(nèi)存空間嘴脾。
????在我們定義Handler的時候,細心的朋友就會發(fā)現(xiàn)蔬墩,系統(tǒng)會拋出一個警告提示:“This Handler class should be static or leaks might occur(null)“译打,提示這樣初始化引用可能會造成內(nèi)存溢出耗拓。
????那么我們該怎么樣避免?答案很簡單扶平,拒絕強引用帆离,使用軟引用WeakReference,貼下代碼:
static class MyHandler extends Handler{
WeakReference<Activity>mActivity;
MyHandler(Activityactivity){
mActivity=newWeakReference<Activity>(activity);
}
@Override
publicvoidhandleMessage(Messagemsg){
Activity activity=mActivity.get();
switch(msg.what){
case 1000:
//doing...
break;
}
}
}
????由于Handler加入作為內(nèi)部類结澄,這說明了它必須保留外部類的引用哥谷,例如Activity需要向外面暴露給Handler,Handler必須一直保持他外部類的引用,如果外部類引用為強引用麻献,很容易出現(xiàn)內(nèi)存泄漏的情況们妥。
四、總結(jié)
????總之勉吻,對比純Java環(huán)境监婶,對于面向移動終端的Android系統(tǒng),對于緩存機制比較敏感齿桃,以及對于內(nèi)存管理更加嚴格惑惶。軟引用(SoftReference)適合應用在需要cache的場景,一般面向?qū)崿F(xiàn)內(nèi)存敏感的緩存短纵;弱引用(WeakReference)則是適用在某些場景為了無法防止被回收的規(guī)范性映射带污,它優(yōu)先級最低,一般與引用隊列聯(lián)合使用香到。而且鱼冀,谷歌不推薦使用軟引用。
傻小孩b mark
共勉悠就,寫給在成長路上奮斗的你
喜歡就為我點下喜歡吧:-D千绪,感謝各位讀者閱讀。