Android開發(fā)了解:強引用、軟引用摩疑、弱引用危融、虛引用

  • 強引用(StrongReference)

  1. 強引用是開發(fā)過程中最常用的引用方式,當一個對象具有強引用時雷袋,操作系統(tǒng)進行 GC 回收處理是不會回收強引用的對象吉殃,即使系統(tǒng)內(nèi)存不足,Java虛擬機寧可拋OutOfMemoryError(內(nèi)存溢出錯誤)楷怒,寧可使程序異常終止蛋勺,也不會靠回收強引用的對象來解決內(nèi)存不足的問題。
  2. 只要把強引用對象 str 賦空值 null, 該對象就可以被 GC 垃圾回收器回收鸠删;因為該對象此時不再含有其他強引用抱完。
用法示例:
  // 變量 str 表示強引用,指向 new String("junker") 這個對象
  String str = new String("junker"); 
  • 軟引用(SoftReference)

  1. 當JVM虛擬機內(nèi)存充足時刃泡,軟引用對象不會被 GC 垃圾回收器回收巧娱。
  2. 當JVM虛擬機內(nèi)存不足時,軟引用對象會被 GC 垃圾回收器回收捅僵。
  3. 未被回收的軟引用對象是一直會被程序占有的家卖。
用法示例:
  MySoftObj softObj = new MySoftObj();
  //軟引用實例
  SoftReference softRef = new SoftReference(softObj);
  //獲取軟引用保存的引用
  MySoftObj anotherRef = (MySoftObj) softRef.get();
  1. 軟引用可以和引用隊列(ReferenceQueue)聯(lián)合使用來實現(xiàn)內(nèi)存緊張的高速緩存;如果軟引用引用的對象被回收庙楚,Java虛擬機會把改軟引用對象加到與之關(guān)聯(lián)的引用隊列中上荡。
用法示例:
  MySoftObj softObj = new MySoftObj();
  ReferenceQueue queue = new  ReferenceQueue();
  SoftReference  softRef = new  SoftReference(softObj, queue);
  • 例如 對于處理圖片這種占用內(nèi)存大的邏輯,可以通過軟引用緩存起來馒闷。但是在實踐中酪捡,使用軟引用作為緩存時效率是比較低的,系統(tǒng)并不知道哪些軟引用指向的對象應該被回收纳账,哪些應該被保留逛薇。過早被回收的對象會導致不必要的工作,比如 Bitmap 要重新從 SdCard 或者 網(wǎng)絡上加載 到內(nèi)存疏虫。在Android開發(fā)中永罚,一種更好的選擇是使用 LruCache啤呼。
  • 弱引用(WeakReference)

用法示例:
  MyWeakObj weakObj = new MyWeakObj();
  //弱引用實例 
  WeakReference weakReference = new WeakReference<>(weakObj); 
  //獲取弱引用保存的引用 
  MyWeakObj anotherRef = weakReference.get(); 
  1. 對于弱引用對象,當操作系統(tǒng)進行 GC 回收處理時呢袱,不管內(nèi)存空間是否足夠官扣,弱引用對象都會被回收。
  2. 如果一個對象除了具有弱引用還具有強引用羞福,GC回收時惕蹄,該對象是不會被回收的,操作系統(tǒng)只會回收只具有弱引用的對象治专。
  3. 弱引用常常被用于防止內(nèi)存泄漏卖陵,最常見的是單例和Handler造成的內(nèi)存泄漏。
  • 對于軟引用場景舉個很常用的例子:
    問題:
    匿名內(nèi)部類異步處理耗時邏輯且持有外部Activity強引用张峰,當Activity被結(jié)束時泪蔫,可能會出現(xiàn)因耗時導致匿名內(nèi)部類在Activit結(jié)束后仍然未釋放Activity對象,至Activity對象不能夠被gc回收挟炬,進而引發(fā)內(nèi)存泄漏問題鸥滨。
    解決方案:
    可以把 匿名內(nèi)部類 寫成一個靜態(tài)類 比如叫 staticCallback,staticCallback 持有外部類的 弱引用谤祖。
    回調(diào)的時候判斷下外部類還在不在婿滓,如果在就通知外部類更新,外部類不在就不用管粥喜。關(guān)鍵就是 callback 持有外部類的弱引用凸主。匿名內(nèi)部類都會隱式持有外部類的強引用,所以要把 callback 搞成一個靜態(tài)類额湘。

相關(guān)代碼實現(xiàn):

 /**
     * 將匿名內(nèi)部類對象卿吐,定義成全局變量,
     * 這樣 baseCallBack 的生命周期就和 外部Activity 一樣
     */
    protected BaseCallBack baseCallBack;

    private void startLongTimeRequest() {
        baseCallBack = new BaseCallBack() {
            @Override
            public void onSuccess(String data) {
                //執(zhí)行業(yè)務邏輯
            }
        };
        //執(zhí)行異步耗時請求
        CustomManager.getInstance().requestApi(new BaseCallBackWeak(baseCallBack));
    }

    static class BaseCallBackWeak implements BaseCallBack {
        private WeakReference<BaseCallBack> backWeakReference;

        public BaseCallBackWeak(BaseCallBack callback) {
            this.backWeakReference = new WeakReference<>(callback);
        }

        @Override
        public void onSuccess(String data) {
            //判斷弱引用對象是否被回收
            if (backWeakReference != null && backWeakReference.get() != null) {
                backWeakReference.get().onSuccess(data);
            }
        }
    }
  • 虛引用(PhantomReference)

1锋华、虛引用不能保證其保存對象生命周期嗡官,若保存對象只有虛引用,則其有效期完全隨機于GC的回收毯焕,在任何一個不確定的時間內(nèi)衍腥,都可能會被回收;而虛引用與其他幾者的引用不同在于纳猫,在使用PhantomReference婆咸,必須要和Reference聯(lián)合使用。

用法示例:
  MyPhantomObj phantomObj = new MyPhantomObj();
  //引用隊列 
  ReferenceQueue queue = new ReferenceQueue<>(); 
  //虛引用 
  PhantomReference phantomReference = new PhantomReference(phantomObj, queue); 
  //獲取虛引用保存的引用 
  MyPhantomObj anotherRef = phantomReference .get(); 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(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
  • 文/不壞的土叔 我叫張陵属百,是天一觀的道長记劝。 經(jīng)常有香客問我,道長族扰,這世上最難降的妖魔是什么厌丑? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮渔呵,結(jié)果婚禮上怒竿,老公的妹妹穿的比我還像新娘。我一直安慰自己扩氢,他們只是感情好耕驰,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著录豺,像睡著了一般朦肘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上双饥,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天媒抠,我揣著相機與錄音,去河邊找鬼咏花。 笑死趴生,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的迟螺。 我是一名探鬼主播冲秽,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矩父!你這毒婦竟也來了锉桑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤窍株,失蹤者是張志新(化名)和其女友劉穎民轴,沒想到半個月后攻柠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡后裸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年瑰钮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片微驶。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡浪谴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出因苹,到底是詐尸還是另有隱情苟耻,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布扶檐,位于F島的核電站凶杖,受9級特大地震影響,放射性物質(zhì)發(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

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