總結(jié)工作中的Android內(nèi)存泄漏問題

簡單判斷是否有內(nèi)存泄漏

判斷內(nèi)存泄漏的定位的大單位是Activity裆赵。

可以通過反復(fù)進(jìn)入退出一個(gè)Activity,然后用adb shell dumpsys meminfo + 包名 查看虛擬機(jī)的堆是否有不斷地增長


定位內(nèi)存泄漏

1.使用Leak Canary

在代碼上加入Leak Canary跺嗽,然后不斷跑Monkey或者手動(dòng)反復(fù)進(jìn)出不同頁面战授。若出現(xiàn)內(nèi)存泄漏問題,會(huì)自動(dòng)導(dǎo)出來桨嫁,生成以下頁面植兰。

內(nèi)存泄漏的引用關(guān)系圖

2.使用DDMS導(dǎo)出hprof,并用MAT工具進(jìn)行分析

0)強(qiáng)烈建議先跑30分鐘Monkey測試

1)使用eclipse的ddms找到對(duì)應(yīng)的進(jìn)程璃吧,觸發(fā)一次gc后楣导,dump出里面的內(nèi)存快照hprof文件以分析當(dāng)前應(yīng)用內(nèi)存的堆有什么東西

2)使用Android SDK 里的platform-tools文件夾的 hprof-conv工具,對(duì)剛才 hprof 文件進(jìn)行轉(zhuǎn)換畜挨,以至于 后面MAT工具能正常打開

3)使用MAT打開hprof文件筒繁,進(jìn)入Histogram。輸入自己猜測可能泄漏的Activity(項(xiàng)目中Activity不多時(shí)巴元,可每個(gè)Activity都重復(fù)以下3毡咏、4、5步驟)

在MAT中搜索BrowserActiviy

4)右鍵該其中一項(xiàng)逮刨,打開菜單選擇list objects ->with incoming refs將列出該類的實(shí)例

下圖展示了對(duì)象間的引用關(guān)系呕缭。

BrowserActivity在內(nèi)存中的引用關(guān)系

5)右健Path to GC Roots-->exclue all phantom/weak/soft etc. reference,找出這個(gè)實(shí)例GC后禀忆,還會(huì)存在什么對(duì)象的引用關(guān)系臊旭。

下圖的情況是:NetworkChangeNotifier類導(dǎo)致BrowserActivity導(dǎo)致內(nèi)存泄漏

導(dǎo)致BrowserActivity內(nèi)存泄漏的引用關(guān)系圖

常見導(dǎo)致內(nèi)存泄漏的幾個(gè)點(diǎn)

生命周期的原因

比如:Activity中關(guān)聯(lián)了一個(gè)生命周期超過Activity的Thread,這個(gè)Thread 若持有該Activity的引用箩退,就會(huì)導(dǎo)致內(nèi)存泄漏离熏。

內(nèi)部類的原因

因?yàn)閮?nèi)部類會(huì)隱式地持有外部類的引用,若內(nèi)部類不被釋放戴涝,外部類也是無法釋放滋戳。常見的有內(nèi)部的Listener钻蔑、Callback、Handler等導(dǎo)致奸鸯。

情景1:若外部類應(yīng)該釋放的時(shí)候咪笑,內(nèi)部類還在執(zhí)行里面的函數(shù),會(huì)導(dǎo)致外部類無法釋放娄涩。

情景2:若一個(gè)異步操作窗怒,會(huì)回調(diào)內(nèi)部類的Listener、Callback蓄拣、Handler扬虚。當(dāng)外部類應(yīng)該釋放的時(shí)候,但是這個(gè)異步操作還存在球恤,而這個(gè)異步操作類又持有了Listener辜昵、Callback、Handler咽斧,導(dǎo)致外部類無法被釋放堪置。PS:這個(gè)原因也屬于生命周期的原因。

靜態(tài)變量的原因

單例類里包含Activity

靜態(tài)變量的類里引用到Activity

注冊(cè)與反注冊(cè)张惹、打開與關(guān)閉沒成對(duì)出現(xiàn)的原因

比如:注冊(cè)廣播接收器舀锨、注冊(cè)觀察者(典型的譬如數(shù)據(jù)庫的監(jiān)聽)等⊥鸲海或者自己寫的跟Activity引用有關(guān)的clear()函數(shù)沒有成對(duì)出現(xiàn)


解決方法

1)解決內(nèi)部類的問題(以Handler作為例子)

  1. onDestroy時(shí)候remove所有msgActivity finish后未處理的msg是問題根源雁竞,所以清空所有未被執(zhí)行的msg
mHandler.removeCallbacksAndMessages(null);

PS:比如Listener、Callback等其他內(nèi)部類的問題拧额,頁面退出的時(shí)候,應(yīng)該完成必要的清理操作彪腔,比如Cancel 請(qǐng)求

  1. 使用靜態(tài)內(nèi)部類 + weakReference
    靜態(tài)內(nèi)部類不會(huì)保留對(duì)外部類的引用侥锦,如果一定要引用外部類,使用weakReference
    static class MyHandler extends Handler {
        WeakReference<Activity > mActivityReference;
        MyHandler(Activity activity) {
            mActivityReference= new WeakReference<Activity>(activity);
        }
    
        @Override
        public void handleMessage(Message msg) {
            final Activity activity = mActivityReference.get();
            if (activity != null) {
                mImageView.setImageBitmap(mBitmap);
            }
        }
    }

PS:比如Listener德挣、Callback等其他內(nèi)部類的問題恭垦,也可以通過這個(gè)方法來解決

2)單例類里面盡量不要傳入Activity,最好穿入ApplicationContext格嗅。假如傳入了Activity番挺,持有的時(shí)長也不能大于Activity的生命周期

3)對(duì)象的注冊(cè)與反注冊(cè)要成對(duì)出現(xiàn)

4)不使用WebView對(duì)象時(shí),應(yīng)該調(diào)用它的destory()函數(shù)來銷毀它屯掖,并釋放其占用的內(nèi)存

5)因?yàn)閂iew會(huì)持有Context玄柏,所以注意不要異步引用View,不要讓靜態(tài)對(duì)象持有View贴铜,不要在集合框架中存儲(chǔ)View

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粪摘,一起剝皮案震驚了整個(gè)濱河市瀑晒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徘意,老刑警劉巖苔悦,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異椎咧,居然都是意外死亡玖详,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門勤讽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蟋座,“玉大人,你說我怎么就攤上這事地技◎谄撸” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵莫矗,是天一觀的道長飒硅。 經(jīng)常有香客問我,道長作谚,這世上最難降的妖魔是什么三娩? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮妹懒,結(jié)果婚禮上雀监,老公的妹妹穿的比我還像新娘。我一直安慰自己眨唬,他們只是感情好会前,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著匾竿,像睡著了一般瓦宜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岭妖,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天临庇,我揣著相機(jī)與錄音,去河邊找鬼昵慌。 笑死假夺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的斋攀。 我是一名探鬼主播已卷,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蜻韭!你這毒婦竟也來了悼尾?” 一聲冷哼從身側(cè)響起柿扣,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闺魏,沒想到半個(gè)月后未状,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡析桥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年司草,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泡仗。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡埋虹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娩怎,到底是詐尸還是另有隱情搔课,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布截亦,位于F島的核電站爬泥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏崩瓤。R本人自食惡果不足惜袍啡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望却桶。 院中可真熱鬧境输,春花似錦、人聲如沸颖系。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘁扼。三九已至窗悯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怕轿。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國打工捌肴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呕乎。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蛤签。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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