Android開發(fā)優(yōu)化之的強引用、軟引用崩侠、弱引用的使用

Android開發(fā)優(yōu)化之的強引用漆魔、軟引用、弱引用的使用

Anderson大碼渣關注

2016.12.27 22:42*字數 1951閱讀 4371評論 16喜歡 122

nougat.png

引言

早在JDK1.2却音,Java就把對象的引用分為四種級別改抡,從而使程序能更加靈活的控制對象的生命周期。這四種級別由高到低依次為:強引用系瓢、軟引用雀摘、弱引用和虛引用。

但是平時我們的代碼中似乎很少出現(xiàn)這些, 而之前還看到過一份代碼中, 一個Activity中有一個靜態(tài)變量持有對自己的弱引用,來達到類似的singleTask的效果.

So, 是時候系統(tǒng)的學習一下軟引用八拱、弱引用這些,并對我們的代碼進行優(yōu)化了.

強引用

String str =newString("xiamin");

強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它肌稻。當內存空間不足清蚀,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程序異常終止爹谭,也不會靠隨意回收具有強引用的對象來解決內存不足的問題枷邪。

強引用特點:

強引用可以直接訪問目標對象。

強引用所指向的對象在任何時候都不會被系統(tǒng)回收诺凡。JVM寧愿拋出OOM異常东揣,也不會回收強引用所指向的對象。

強引用可能導致內存泄露腹泌。

軟引用 (SoftReference)

簡單用法

MyObject aRef =newMyObject();? ? SoftReference aSoftRef=newSoftReference(aRef);? ? ? ? MyObject anotherRef=(MyObject)aSoftRef.get();

java.lang.ref包中提供了幾個類:SoftReference類嘶卧、WeakReference類和PhantomReference類,它們分別代表軟引用凉袱、弱引用和虛引用芥吟。ReferenceQueue類表示引用隊列,它可以和這三種引用類聯(lián)合使用专甩,以便跟蹤Java虛擬機回收所引用的對象的活動钟鸵。

如果一個對象只具有軟引用,那么如果內存空間足夠涤躲,垃圾回收器就不會回收它棺耍;如果內存空間不足了,就會回收這些對象的內存种樱。只要垃圾回收器沒有回收它蒙袍,該對象就可以被程序使用。軟引用可用來實現(xiàn)內存敏感的高速緩存缸托。軟引用可以和一個引用隊列(ReferenceQueue)聯(lián)合使用左敌,如果軟引用所引用的對象被垃圾回收,Java虛擬機就會把這個軟引用加入到與之關聯(lián)的引用隊列中俐镐。

ReferenceQueue queue =newReferenceQueue();? ? SoftReference? ref=newSoftReference(aMyObject, queue);

那么當這個SoftReference所軟引用的aMyOhject被垃圾收集器回收的同時矫限,ref所強引用的SoftReference對象被列入ReferenceQueue。也就是說佩抹,ReferenceQueue中保存的對象是Reference對象叼风,而且是已經失去了它所軟引用的對象的Reference對象。另外從ReferenceQueue這個名字也可以看出棍苹,它是一個隊列无宿,當我們調用它的poll()方法的時候,如果這個隊列中不是空隊列枢里,那么將返回隊列前面的那個Reference對象孽鸡。

在任何時候蹂午,我們都可以調用ReferenceQueue的poll()方法來檢查是否有它所關心的非強可及對象被回收。如果隊列為空彬碱,將返回一個null,否則該方法返回隊列中前面的一個Reference對象豆胸。利用這個方法,我們可以檢查哪個SoftReference所軟引用的對象已經被回收巷疼。于是我們可以把這些失去所軟引用的對象的SoftReference對象清除掉晚胡。常用的方式為:

SoftReference ref =null;while((ref = (EmployeeRef) q.poll()) !=null) {// 清除ref}

當然,我們作為Android開發(fā)中使用,正常是用來處理圖片這種占用內存大的類的.

所以,我們應該這樣使用.

View view = findViewById(R.id.button);? ? Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);? ? Drawable drawable =newBitmapDrawable(bitmap);? ? SoftReference drawableSoftReference =newSoftReference(drawable);? ? ? ? Drawable bgdrawable = drawableSoftReference.get();if(bgdrawable !=null) {? ? ? ? view.setBackground(bgdrawable);? ? }

這樣的好處是

通過軟引用的get()方法,取得drawable對象實例的強引用嚼沿,發(fā)現(xiàn)對象被未回收估盘。在GC在內存充足的情況下,不會回收軟引用對象骡尽。此時view的背景顯示.

實際情況中,我們會獲取很多圖片.然后可能給很多個view展示, 這種情況下很容易內存吃緊導致oom,

內存吃緊遣妥,系統(tǒng)開始會GC。這次GC后爆阶,drawables.get()不再返回Drawable對象燥透,而是返回null,這時屏幕上背景圖不顯示辨图,說明在系統(tǒng)內存緊張的情況下班套,軟引用被回收。

使用軟引用以后故河,在OutOfMemory異常發(fā)生之前吱韭,這些緩存的圖片資源的內存空間可以被釋放掉的,從而避免內存達到上限鱼的,避免Crash發(fā)生理盆。

需要注意的是,在垃圾回收器對這個Java對象回收前凑阶,SoftReference類所提供的get方法會返回Java對象的強引用猿规,一旦垃圾線程回收該Java對象之后,get方法將返回null宙橱。所以在獲取軟引用對象的代碼中姨俩,一定要判斷是否為null,以免出現(xiàn)NullPointerException異常導致應用崩潰师郑。

弱引用 (WeakReference)

用法

WeakReference sr =newWeakReference(newUser());

如果一個對象只具有弱引用环葵,那么在垃圾回收器線程掃描的過程中,一旦發(fā)現(xiàn)了只具有弱引用的對象宝冕,不管當前內存空間足夠與否张遭,都會回收它的內存。不過地梨,由于垃圾回收器是一個優(yōu)先級很低的線程菊卷,因此不一定會很快發(fā)現(xiàn)那些只具有弱引用的對象缔恳。弱引用也可以和一個引用隊列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對象被垃圾回收的烁,Java虛擬機就會把這個弱引用加入到與之關聯(lián)的引用隊列中褐耳。

弱引用與軟引用的根本區(qū)別在于:只具有弱引用的對象擁有更短暫的生命周期,可能隨時被回收渴庆。而只具有軟引用的對象只有當內存不夠的時候才被回收,在內存足夠的時候雅镊,通常不被回收襟雷。

使用場景,handler的使用防止內存泄露

importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Message;importandroid.support.v7.app.AppCompatActivity;importjava.lang.ref.WeakReference;publicclassMainActivityextendsAppCompatActivity{privateHandler handler? ;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);? ? ? ? handler =newMyHandler(this) ;newThread(newRunnable() {@Overridepublicvoidrun(){? ? ? ? ? ? ? handler.sendEmptyMessage(0) ;? ? ? ? ? ? }? ? ? ? }).start() ;? ? }privatestaticclassMyHandlerextendsHandler{? ? ? ? WeakReference weakReference ;publicMyHandler(MainActivity activity ){? ? ? ? ? ? weakReference? =newWeakReference( activity) ;? ? ? ? }@OverridepublicvoidhandleMessage(Message msg){super.handleMessage(msg);if( weakReference.get() !=null){// update android ui}? ? ? ? }? ? } }

在Android應用的開發(fā)中,為了防止內存溢出仁烹,在處理一些占用內存大而且聲明周期較長的對象時候耸弄,可以盡量應用軟引用和弱引用技術。

軟引用卓缰,弱引用都非常適合來保存那些可有可無的緩存數據计呈。如果這樣做,當系統(tǒng)內存不足時征唬,這些緩存數據會被回收捌显,不會導致內存溢出。而當內存資源充足時总寒,這些緩存數據又可以存在相當長的時間扶歪。

到底什么時候使用軟引用,什么時候使用弱引用呢摄闸?

個人認為善镰,如果只是想避免OutOfMemory異常的發(fā)生,則可以使用軟引用年枕。如果對于應用的性能更在意炫欺,想盡快回收一些占用內存比較大的對象,則可以使用弱引用熏兄。

還有就是可以根據對象是否經常使用來判斷品洛。如果該對象可能會經常使用的,就盡量用軟引用霍弹。如果該對象不被使用的可能性更大些毫别,就可以用弱引用。

另外典格,和弱引用功能類似的是WeakHashMap岛宦。WeakHashMap對于一個給定的鍵,其映射的存在并不阻止垃圾回收器對該鍵的回收耍缴,回收以后砾肺,其條目從映射中有效地移除挽霉。WeakHashMap使用ReferenceQueue實現(xiàn)的這種機制。

謝謝大家閱讀变汪,如有幫助侠坎,來個喜歡或者關注吧!

本文作者:Anderson/Jerey_Jobs

簡書地址? :Anderson大碼渣

CSDN地址? :Jerey_Jobs的專欄

github地址 :Jerey_Jobs

? ? ? ? ? ? ? 上一篇


目錄

? ? ? ? ? ? ? 下一篇


小禮物走一走裙盾,來簡書關注我

贊賞支持

andriod學習

? ? ? ? ? ? 著作權歸作者所有


舉報文章

? ? ? ? ? ? ? andriod學習


5.2萬字 ·3.9萬閱讀·113人關注



關注

喜歡

122

? ? ? ?

? ? ? ?

? ? ? ? ? 更多分享

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末实胸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子番官,更是在濱河造成了極大的恐慌庐完,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徘熔,死亡現(xiàn)場離奇詭異门躯,居然都是意外死亡,警方通過查閱死者的電腦和手機酷师,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門讶凉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人山孔,你說我怎么就攤上這事懂讯。” “怎么了饱须?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵域醇,是天一觀的道長。 經常有香客問我蓉媳,道長譬挚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任酪呻,我火速辦了婚禮减宣,結果婚禮上,老公的妹妹穿的比我還像新娘玩荠。我一直安慰自己漆腌,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布阶冈。 她就那樣靜靜地躺著闷尿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪女坑。 梳的紋絲不亂的頭發(fā)上填具,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音,去河邊找鬼劳景。 笑死誉简,一個胖子當著我的面吹牛,可吹牛的內容都是我干的盟广。 我是一名探鬼主播闷串,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼筋量!你這毒婦竟也來了烹吵?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤毛甲,失蹤者是張志新(化名)和其女友劉穎年叮,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體玻募,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年一姿,在試婚紗的時候發(fā)現(xiàn)自己被綠了七咧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡叮叹,死狀恐怖艾栋,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蛉顽,我是刑警寧澤蝗砾,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站携冤,受9級特大地震影響悼粮,放射性物質發(fā)生泄漏。R本人自食惡果不足惜曾棕,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一扣猫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翘地,春花似錦申尤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至橙喘,卻和暖如春时鸵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背渴杆。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工寥枝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宪塔,地道東北人甘畅。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓衬吆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親啥酱。 傳聞我的和親對象是個殘疾皇子冠跷,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容