Mvp 框架 中 v層與p層之間如何防止內(nèi)存泄漏?(面試題)

1邪锌、內(nèi)存泄漏原因


內(nèi)存泄漏就是當(dāng) GC 來回收時(shí)勉躺,然而這些對(duì)象沒有得到釋放,或者被其它的給引用了觅丰,這種情況下 GC 是不會(huì)自動(dòng)回收的饵溅,而這塊內(nèi)存就會(huì)被一直占用著,得不到釋放妇萄,這就是內(nèi)存泄漏的基本概念蜕企。然而咬荷,程序這樣的情況越來越多時(shí),程序就會(huì)出現(xiàn)卡頓轻掩、奔潰萍丐、報(bào)異常的現(xiàn)象,當(dāng)這些對(duì)象占用的內(nèi)存達(dá)到一定的臨界值時(shí)放典,機(jī)器中沒有多余可用的內(nèi)存逝变,這時(shí)你再去申請(qǐng)內(nèi)存空間,就會(huì)發(fā)生 OOM (內(nèi)存溢出)奋构。所以說壳影,內(nèi)存泄漏是一種安全隱患,它直接影響的是程序的性能弥臼。要想在這方面做的好宴咧,這需要一個(gè)深入的研究。

1径缅、Mvp項(xiàng)目中

BaseMVP 其實(shí)也是會(huì)造成內(nèi)存泄漏的一大安全隱患掺栅,它的內(nèi)存泄漏是來自于 View 層與 Presenter 層之間的強(qiáng)引用關(guān)系。我們?cè)?Presenter 層直接綁定了 View 才可以拿到 View 層的引用纳猪,它們之間是強(qiáng)引用的關(guān)系氧卧,如果不進(jìn)行解綁的話,那就會(huì)造成內(nèi)存泄漏的情況發(fā)生氏堤。為什么不解綁就會(huì)內(nèi)存泄漏呢沙绝?我們來看看代碼:

(不是最終版代碼)
public abstract class BasePresenter<V extends IBaseView> implements IBasePresenter {
    protected V mView;
 
    @SuppressWarnings("unchecked")
    @Override
    public void attech(IBaseView view) {
        mView = (V) view;
    }
 
    @Override
    public void detech() {
//        mView = null;
    }
}

這里,我們不解綁 View鼠锈,也就是 mView = null 注釋掉闪檬,意味著 Presenter 層還持有 View 的引用,當(dāng) Activity 被關(guān)閉時(shí)购笆,Activity 相當(dāng)于 View 層粗悯,由于 Activity 還是被 Presenter 層引用了,當(dāng) GC 來了同欠,它一看 Activity 被引用了样傍,所以就不會(huì)去回收它。當(dāng)你再次打開 Activity 又關(guān)閉時(shí)行您,Activity 又申請(qǐng)了一段新的內(nèi)存空間铭乾,GC 又沒去回收它,久而久之娃循,勢(shì)必會(huì)內(nèi)存溢出炕檩。
而這里置空了就不會(huì)造成內(nèi)存泄漏,因?yàn)榇藭r(shí)的 View,也就是 Activity 的引用被釋放了笛质,如果再也沒有其他類引用到 Activity 對(duì)象的時(shí)候泉沾,當(dāng) GC 來時(shí),發(fā)現(xiàn) Activity 是可以回收的妇押,就把它回收掉了跷究,這段內(nèi)存空間就釋放了。
說了這么多敲霍,其實(shí)就是為了介紹我們自己寫的 BaseMVP 存在的內(nèi)存泄漏問題俊马,這里的代碼還是基于上一篇 MVP v2 版本進(jìn)行修改,因?yàn)?V 與 P 之間是強(qiáng)引用肩杈,
所以我們就改為弱引用用的方式柴我,避免內(nèi)存泄漏導(dǎo)致的 OOM 情況發(fā)生。

(此為kotin代碼)
open class BasePresenter<V: IBaseView>:
    IPresenter<V> {

    protected var mView:V? = null
    private var weakReference:WeakReference<V>? = null
    protected var compositeDisposable:CompositeDisposable? = null

    override fun attachView(view: V) {
        weakReference = WeakReference(view)
        mView = weakReference!!.get()
    }

    protected fun addSubscribe(disposable:Disposable){
        if(compositeDisposable == null) compositeDisposable = CompositeDisposable()
        compositeDisposable!!.add(disposable)
    }

    protected fun unSubscribe(){
        if(compositeDisposable != null){
            compositeDisposable!!.clear()
        }
    }

    override fun detachView() {
        this.mView = null
    }
}

使用弱引用的方式讓 P 層持有 V 層的引用扩然,并且提供了 get() 方法給 P 層調(diào)用艘儒,父類 View 變量進(jìn)行私有化,防止子類對(duì)其進(jìn)行更改造成的其他錯(cuò)誤夫偶。我們的 MainPresenter 獲取 Activity 的引用就可以使用 get() 方法獲得界睁。弱引用在內(nèi)存降到不足的情況下,GC 就會(huì)進(jìn)行優(yōu)先回收釋放那些以弱引用方式引用的對(duì)象兵拢,一定程度上去避免內(nèi)存溢出(OOM)翻斟。

動(dòng)態(tài)代理

每次都要讓 View 做空判斷,很煩卵佛?

為什么要用動(dòng)態(tài)代理呢杨赤?我們看上面的 get()代碼敞斋,沒次都需要判斷 null 類型截汪,是不是非常麻煩,又因?yàn)檫@里的 View 類型是一個(gè)接口(V extends IBaseView)泛型接口植捎,所以這就好辦了衙解,動(dòng)態(tài)代理完全就可以做到統(tǒng)一的空類型判斷。
使用動(dòng)態(tài)代理之后焰枢,我們?cè)?Presenter 的實(shí)現(xiàn)類中就不需要做 View 層的空類型判斷了蚓峦,這樣既節(jié)省了代碼,雖然沒有多少代碼济锄,但是寫起來還是很煩的暑椰,又讓我們的代碼變得更加優(yōu)雅。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末一汽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌召夹,老刑警劉巖岩喷,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異监憎,居然都是意外死亡纱意,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門鲸阔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偷霉,“玉大人,你說我怎么就攤上這事褐筛√谒” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵死讹,是天一觀的道長(zhǎng)瞒滴。 經(jīng)常有香客問我,道長(zhǎng)赞警,這世上最難降的妖魔是什么妓忍? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮愧旦,結(jié)果婚禮上世剖,老公的妹妹穿的比我還像新娘。我一直安慰自己笤虫,他們只是感情好旁瘫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著琼蚯,像睡著了一般酬凳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遭庶,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天宁仔,我揣著相機(jī)與錄音,去河邊找鬼峦睡。 笑死翎苫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的榨了。 我是一名探鬼主播煎谍,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼龙屉!你這毒婦竟也來了呐粘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎事哭,沒想到半個(gè)月后漫雷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鳍咱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年降盹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谤辜。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蓄坏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丑念,到底是詐尸還是另有隱情涡戳,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布脯倚,位于F島的核電站渔彰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏推正。R本人自食惡果不足惜恍涂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望植榕。 院中可真熱鬧再沧,春花似錦、人聲如沸尊残。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寝衫。三九已至顷扩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竞端,已是汗流浹背屎即。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留事富,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓乘陪,卻偏偏與公主長(zhǎng)得像统台,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子啡邑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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

  • 1贱勃、Activity生命周期? onCreate() -> onStart() -> onResume() -> ...
    王培921223閱讀 2,384評(píng)論 0 11
  • 所有知識(shí)點(diǎn)已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,429評(píng)論 1 4
  • 【Android 內(nèi)存泄漏】 引用: ★★★ 【知識(shí)必備】?jī)?nèi)存泄漏全解析贵扰,從此拒絕ANR仇穗,讓OOM遠(yuǎn)離你的身邊,跟...
    Rtia閱讀 816評(píng)論 0 2
  • 部署項(xiàng)目可以分為構(gòu)建戚绕、發(fā)布兩個(gè)步驟纹坐。構(gòu)建過程打包源代碼,生成最終運(yùn)行的文件舞丛,發(fā)布過程使用打包后的文件更新線上程序耘子。...
    wuww閱讀 497評(píng)論 0 0
  • 文/執(zhí)筆成書 新的一年已然開始了,又要開始一年的生活了球切,在這新的一年里谷誓,還有很多事要做。 第一吨凑,我得努力學(xué)習(xí)捍歪,并且...
    執(zhí)筆成書閱讀 130評(píng)論 0 2