Java中內(nèi)存優(yōu)化的SoftReference 和 WeakReference淺析

一香追、引用對象類型定義

????首先怜奖,引用對象在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)境運行情況:

java運行.png

Android環(huán)境運行情況:

Android運行.png

????從上面的情況,我們還讓你容易可以觀察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)存溢出耗拓。

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加入作為內(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千绪,感謝各位讀者閱讀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梗脾,一起剝皮案震驚了整個濱河市荸型,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炸茧,老刑警劉巖帆疟,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宇立,居然都是意外死亡踪宠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門妈嘹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柳琢,“玉大人,你說我怎么就攤上這事〖砹常” “怎么了他去?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長倒堕。 經(jīng)常有香客問我灾测,道長,這世上最難降的妖魔是什么垦巴? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任媳搪,我火速辦了婚禮,結(jié)果婚禮上骤宣,老公的妹妹穿的比我還像新娘秦爆。我一直安慰自己,他們只是感情好憔披,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布等限。 她就那樣靜靜地躺著,像睡著了一般芬膝。 火紅的嫁衣襯著肌膚如雪望门。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天锰霜,我揣著相機與錄音筹误,去河邊找鬼。 笑死锈遥,一個胖子當著我的面吹牛纫事,可吹牛的內(nèi)容都是我干的勘畔。 我是一名探鬼主播所灸,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼炫七!你這毒婦竟也來了爬立?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤万哪,失蹤者是張志新(化名)和其女友劉穎侠驯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奕巍,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡吟策,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了的止。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片檩坚。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出匾委,到底是詐尸還是另有隱情拖叙,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布赂乐,位于F島的核電站薯鳍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挨措。R本人自食惡果不足惜挖滤,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望运嗜。 院中可真熱鬧壶辜,春花似錦、人聲如沸担租。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奋救。三九已至岭参,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尝艘,已是汗流浹背演侯。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留背亥,地道東北人秒际。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像狡汉,于是被迫代替她去往敵國和親娄徊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容