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


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

一、引用對象類型定義

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

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

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

    在強引用中,如果不讓該對象指向為空,垃圾回收器絕對不會回收它。除非當出現內存空間不足的時候。jvm拋出oom導致程序異常種植的時候,才會回收具有強引用的對象來解決內存空間不足問題。

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

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

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 

二、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環境中輸出結果一致,這個筆者也匪夷所思...

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

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

 
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必須一直保持他外部類的引用,如果外部類引用為強引用,很容易出現內存泄漏的情況。

四、總結

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



作者:DevSiven
鏈接:https://www.jianshu.com/p/b56731447179
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM