AsynTask與handler引起的內(nèi)存泄漏如何解決

前言

內(nèi)存泄漏其實(shí)是用戶無(wú)感的薪夕,可能一次或幾次的泄漏危害可以忽略,但內(nèi)存泄漏堆積后赫悄,會(huì)影響app的性能原献,嚴(yán)重可能會(huì)導(dǎo)致oom,內(nèi)存溢出涩蜘。

小伙伴們?cè)趯?shí)際開發(fā)中嚼贡,要防止內(nèi)存泄漏的產(chǎn)生。大家可以通過(guò)內(nèi)存檢測(cè)工具同诫,來(lái)查看你的項(xiàng)目是否有內(nèi)存泄漏的產(chǎn)生粤策。

防止內(nèi)存泄漏的方法有許多,這里只列舉了handler與Asyntask防止內(nèi)存的產(chǎn)生误窖,因?yàn)楸容^實(shí)用叮盘,未了解的小伙伴可以收藏一下。

一霹俺、舉個(gè)栗子

這是某內(nèi)存檢測(cè)工具柔吼,是handler引起的內(nèi)存泄漏錯(cuò)誤信息

In com.ophone.reader.ui:6.8.3:118.
* com.cmread.bplusc.reader.ui.share.ShareToFXActivity has leaked:
* GC ROOT static com.cmread.bplusc.httpservice.http.HttpMessageQueue.mSelf
* references com.cmread.bplusc.httpservice.http.HttpMessageQueue.mCallback
* references com.cmread.bplusc.httpservice.http.HttpQueueCallback.mICallBack
* references com.cmread.bplusc.presenter.AbsPresenter$1.this$0 (anonymous class implements com.cmread.bplusc.httpservice.aidl.ICallBack)
* references com.cmread.bplusc.presenter.GetShareLinkPresenter.mUIHandler
* references com.cmread.bplusc.reader.ui.share.ShareToFXActivity$1.this$0 (anonymous class extends android.os.Handler)
* leaks com.cmread.bplusc.reader.ui.share.ShareToFXActivity instance

從上述日志中可以得出,ShareToFxActivity有泄漏的產(chǎn)生丙唧,這里的mSelf指的就是ShareToFxActivity愈魏,因?yàn)樵谄渌胤接衜Self的引用,從而導(dǎo)致改Activity在finish的時(shí)候無(wú)法被GC回收。在mCallback是通過(guò)handler做的異步回調(diào)培漏,在回調(diào)時(shí)溪厘,finish當(dāng)前activity,但是mSelf還在指向其他引用牌柄。

其實(shí)光從app的功能實(shí)現(xiàn)上畸悬,并不會(huì)產(chǎn)生感官上的差異,但是上面也說(shuō)了珊佣,內(nèi)存泄漏堆積后蹋宦,會(huì)影響你的app性能,嚴(yán)重造成oom咒锻。所以在實(shí)際開發(fā)中冷冗,一定要防止此錯(cuò)誤的產(chǎn)生。

二惑艇、解決方案

簡(jiǎn)單來(lái)說(shuō)贾惦,用戶在退出當(dāng)前界面,即銷毀當(dāng)前activity時(shí)敦捧,如果此時(shí)handler對(duì)象有message在排隊(duì)须板,無(wú)法釋放,就會(huì)導(dǎo)致activity無(wú)法正常銷毀兢卵,從而造成內(nèi)存泄漏习瑰。
解決方案很簡(jiǎn)單:在onDestroy()生命周期中,將handler所有的消息全都移除秽荤,可以有效解決由handler引起的內(nèi)存泄漏甜奄。

  • 可以查看谷歌的官方api
public final void removeCallbacksAndMessages([Object] token)
  Added in [API level 1]
  Remove any pending posts of callbacks and sent messages whose obj is token. Iftoken
 is null, all callbacks and messages will be removed.

意思是當(dāng)傳入的參數(shù)為null時(shí),則會(huì)移除所有的callbacks和message窃款,這樣就有效避免了Handler引起的內(nèi)存泄漏课兄。
具體代碼

    @Override
    protected void onDestroy() {
        if(mHandler != null){
            mHandler.removeCallbacksAndMessages(null);
        }
        //do something 
        super.onDestroy();
    }

三、AsynTask引起的內(nèi)存泄漏

其實(shí)AsynTask引起的原因與handler類似晨继,在activity結(jié)束的時(shí)候就結(jié)束了任務(wù)烟阐。但是相對(duì)于其他情況(比如說(shuō)操作網(wǎng)絡(luò)的時(shí)候),doInBackground方法里面還是會(huì)繼續(xù)執(zhí)行紊扬,并且執(zhí)行完之后還會(huì)繼續(xù)onPostExecute方法蜒茄,此時(shí)如果用戶網(wǎng)絡(luò)較慢,還在進(jìn)行網(wǎng)絡(luò)請(qǐng)求中餐屎,用戶沒(méi)耐心了檀葛,不想等,退出當(dāng)前activity腹缩,那么必定會(huì)因?yàn)锳synTask引起的內(nèi)存泄漏屿聋,導(dǎo)致activity無(wú)法正常銷毀空扎。

  • 解決方案
   @Override
    protected void onDestroy() {
        if(mMyTask != null && mMyTask.isCancelled()){
            //及時(shí)結(jié)束異步任務(wù)
            mMyTask.cancel(true);
            mMyTask = null;
        }
        //do something
        super.onDestroy();
    }

總結(jié)

雖然內(nèi)存泄漏可能是無(wú)感知的,但是長(zhǎng)期如此危害是相當(dāng)?shù)娜蠹ァ=鉀Q內(nèi)存泄漏要從細(xì)節(jié)做起勺卢,一定要受到開發(fā)者的足夠重視。
解決內(nèi)存泄漏有許多入手象对,這里舉的兩個(gè)例子是非常使用,解決方案也非常簡(jiǎn)單宴抚。但是非常讓人忽略勒魔,如果沒(méi)有工具,可能還無(wú)法知道這種現(xiàn)象產(chǎn)生菇曲,所以未了解的童鞋冠绢,可以正好漲漲姿勢(shì)……

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市常潮,隨后出現(xiàn)的幾起案子弟胀,更是在濱河造成了極大的恐慌,老刑警劉巖喊式,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孵户,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岔留,警方通過(guò)查閱死者的電腦和手機(jī)夏哭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)献联,“玉大人竖配,你說(shuō)我怎么就攤上這事±锬妫” “怎么了进胯?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)原押。 經(jīng)常有香客問(wèn)我胁镐,道長(zhǎng),這世上最難降的妖魔是什么诸衔? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任希停,我火速辦了婚禮,結(jié)果婚禮上署隘,老公的妹妹穿的比我還像新娘宠能。我一直安慰自己,他們只是感情好磁餐,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布违崇。 她就那樣靜靜地躺著阿弃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪羞延。 梳的紋絲不亂的頭發(fā)上渣淳,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音伴箩,去河邊找鬼入愧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嗤谚,可吹牛的內(nèi)容都是我干的棺蛛。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼巩步,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼旁赊!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起椅野,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤终畅,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后竟闪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體离福,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年炼蛤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了术徊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鲸湃,死狀恐怖赠涮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情暗挑,我是刑警寧澤笋除,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站炸裆,受9級(jí)特大地震影響垃它,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烹看,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一国拇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惯殊,春花似錦酱吝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)忆嗜。三九已至,卻和暖如春崎岂,著一層夾襖步出監(jiān)牢的瞬間捆毫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工冲甘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绩卤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓江醇,卻偏偏與公主長(zhǎng)得像濒憋,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嫁审,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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