java軟引用、弱引用(轉摘)

本文轉自網絡,源地址:https://www.jianshu.com/p/b56731447179

1、引用對象類型定義

    首先,引用對象在Java定義中有三種類型,從弱到強依次爲:軟引用、弱引用與虛引用,三種級別也各有所不一樣(軟引用>弱引用)。本文淺析下軟引用與弱引用。大概的解釋,軟引用適合應用在須要cache的場景,通常面向實現內存敏感的緩存;弱引用則是適用在某些場景爲了沒法防止被回收的規範性映射,它優先級最低,通常與引用隊列聯合使用。javascript

詳細介紹:
(一)強引用(默認存在)
    強引用,是在實際開發中最爲廣泛的引用。有時候你開發的時候,申請一個內存空間的時候,就已是強引用了。例如:java

Object obj =new Object(); // 強引用 

    在強引用中,若是不讓該對象指向爲空,垃圾回收器絕對不會回收它。除非當出現內存空間不足的時候。jvm拋出oom致使程序異常種植的時候,纔會回收具備強引用的對象來解決內存空間不足問題。android

Object obj =new Object(); // 強引用 obj = null;//這時候爲垃圾回收器回收這個對象,至於何時回收,取決於垃圾回收器的算法 

(二)軟引用(SoftReference )
    軟引用對象也比較好理解,它是一個比較特殊的存在,擁有強引用的屬性,又更加安全。若是有一個對象具備軟引用。在內存空間足夠的狀況下,除非內存空間接近臨界值、jvm即將拋出oom的時候,垃圾回收器纔會將該引用對象進行回收,避免了系統內存溢出的狀況。(前提也是對象指向不爲空)所以,SoftReference 引用對象很是適合實現內存敏感的緩存,例如加載圖片的時候,bitmap緩存機制。web

String value = new String(「sy」); SoftReference sfRefer = new SoftReference (value ); sfRefer .get();//能夠得到引用對象值 

(三)弱引用(WeakReference)
    顧名思義,一個具備弱引用的對象,與軟引用對比來講,前者的生命週期更短。當垃圾回收器掃描到弱引用的對象的時候,無論內存空間是否足夠,都會直接被垃圾回收器回收。不過也不用特別擔憂,垃圾回收器是一個優先級比較低的現場,所以不必定很快能夠發現弱引用的對象。
   另外,google官方是推薦Android開發者使用WeakReference,而不建議SoftReference 引用,Android環境下與純Java有所略同。下面待會說明狀況。算法

String value = new String(「sy」); WeakReference weakRefer = new WeakReference(value ); System.gc(); weakRefer.get();//null 

2、Java環境與Android環境對比異同點

下面直接貼一份代碼,同一份代碼,比較在android環境下輸出的結果與Java輸出的結果:緩存

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環境運行狀況:安全

 
java運行.png

Android環境運行狀況:網絡

 
Android運行.png

    從上面的狀況,咱們還讓你容易能夠觀察Android環境下與純Java環境下二者直接的輸出結果不一樣!在Android環境下WeakReference 與SoftReference 二者輸出結果同樣。其實對於手機系統存在多應用,又對於內存是比較敏感的,天然對於內存釋放會更加嚴格。試想一下,若是衆多對象使用 SoftReference引用,大部分都是這也是爲何google不建議SoftReference 的緣由之一,至於軟引用與弱引用在android環境中輸出結果一致,這個筆者也匪夷所思...jvm

3、實戰應用內存優化策略避免Handler內存泄漏

    前,在平常開發中,其實對內存比較敏感的,例如Activity、webView、bitmap、Handler等等,舉例若是咱們擁有一個管理Activity的管理類,即Activity須要暴露在外面,若是當前其中有一個Activity正在執行一個耗時的任務,若是使用強引用,這一系列過程很吃內存空間。
    在咱們定義Handler的時候,細心的朋友就會發現,系統會拋出一個警告提示:「This Handler class should be static or leaks might occur(null)「,提示這樣初始化引用可能會形成內存溢出。ide

 
QQ截圖20160809092738.png

    那麼咱們該怎麼樣避免?答案很簡單,拒絕強引用,使用軟引用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加入做爲內部類,這說明了它必須保留外部類的引用,例如Activity須要向外面暴露給Handler,Handler必須一直保持他外部類的引用,若是外部類引用爲強引用,很容易出現內存泄漏的狀況。

4、總結

    總之,對比純Java環境,對於面向移動終端的Android系統,對於緩存機制比較敏感,以及對於內存管理更加嚴格。軟引用(SoftReference)適合應用在須要cache的場景,通常面向實現內存敏感的緩存;弱引用(WeakReference)則是適用在某些場景爲了沒法防止被回收的規範性映射,它優先級最低,通常與引用隊列聯合使用。並且,谷歌不推薦使用軟引用。

做者:DevSiven連接:https://www.jianshu.com/p/b56731447179來源:簡書簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索