Android常見問題之內(nèi)存泄漏

一复旬、定義

內(nèi)存泄漏是指:應(yīng)該被GC回收的對象無法被回收垦缅,這個對象會引發(fā)內(nèi)存泄漏。

二驹碍、危害

1壁涎、引發(fā)內(nèi)存溢出;
2志秃、導(dǎo)致內(nèi)存不足怔球,頻繁觸發(fā)GC,因而導(dǎo)致UI卡頓浮还;

三竟坛、檢測工具

1、MAT(Memory Analyzer Tools)是一個分析Java堆數(shù)據(jù)的專業(yè)工具钧舌,用它可以定位內(nèi)存泄漏的原因担汤。
MAT 使用方法:
內(nèi)存泄漏 之 MAT工具的使用
2、LeakCanary是一個開源的在debug版本中檢測內(nèi)存泄漏的java庫洼冻。
LeakCanary使用方法:
LeakCanary——直白的展現(xiàn)Android中的內(nèi)存泄露

四崭歧、常見案例和解決方案

1、單例中不合理的持有
單例中的對象生命周期與應(yīng)用一致

解決方案:

  • 將該屬性的引用方式改為弱引用;
  • 如果傳入Context撞牢,使用ApplicationContext;

2率碾、非靜態(tài)內(nèi)部類和匿名類
在Java中,非靜態(tài)內(nèi)部類 和 匿名類 都會潛在的引用它們所屬的外部類屋彪,但是所宰,靜態(tài)內(nèi)部類卻不會。如果這個非靜態(tài)內(nèi)部類實例做了一些耗時的操作畜挥,就會造成外圍對象不會被回收仔粥,從而導(dǎo)致內(nèi)存泄漏。

解決方案:

  • 將內(nèi)部類改為靜態(tài)內(nèi)部類;
  • 如果有強引用Activity中的屬性砰嘁,則將該屬性的引用方式改為弱引用;
  • 在業(yè)務(wù)允許的情況下件炉,當(dāng)Activity執(zhí)行onDestory時,結(jié)束這些耗時任務(wù);

3矮湘、Context的不正確使用
在Android應(yīng)用程序中通痴迕幔可以使用兩種Context對象:Activity Context和Application Context。當(dāng)Activity Context被傳遞到其他實例中缅阳,這可能導(dǎo)致自身被引用而發(fā)生泄漏磕蛇。

解決方案:

  • 對于大部分非必須使用Activity Context的情況,應(yīng)該使用Application Context(因為Application Context會隨著應(yīng)用程序的存在而存在十办,而不依賴于activity的生命周期);
  • 對Context的引用不要超過它本身的生命周期秀撇,慎重的對Context使用“static”關(guān)鍵字;
  • Context里如果有線程向族,一定要在onDestroy()里及時停掉;

4呵燕、Handler引起的內(nèi)存泄漏
當(dāng)Handler中有延遲的的任務(wù)或是等待執(zhí)行的任務(wù)隊列過長,由于消息持有對Handler的引用件相,而Handler又持有對其外部類的潛在引用再扭,這條引用關(guān)系會一直保持到消息得到處理,而導(dǎo)致了Activity無法被垃圾回收器回收夜矗,而導(dǎo)致了內(nèi)存泄露泛范。

解決方案:

  • 可以把Handler類放在單獨的類文件中,或者使用靜態(tài)內(nèi)部類便可以避免泄露;
  • 如果想在Handler內(nèi)部去調(diào)用所在的Activity,那么可以在handler內(nèi)部使用弱引用的方式去指向所在Activity(使用Static + WeakReference的方式來達到斷開Handler與Activity之間存在引用關(guān)系的目的);

5紊撕、沒有注銷監(jiān)聽器
如果Context 對象想要在服務(wù)內(nèi)部的事件發(fā)生時被通知罢荡,那就需要把自己注冊到服務(wù)的監(jiān)聽器中。然而对扶,這會讓服務(wù)持有Activity 的引用区赵,如果在Activity onDestory時沒有釋放掉引用就會內(nèi)存泄漏。

解決方案:

  • 使用Application Context代替Activity Context;
  • 在Activity執(zhí)行onDestory時辩稽,調(diào)用反注冊;

6惧笛、資源對象沒有關(guān)閉
資源性對象比如(Cursor,F(xiàn)ile文件等)往往都用了一些緩沖逞泄,我們在不使用的時候患整,應(yīng)該及時關(guān)閉它們,以便它們的緩沖及時回收內(nèi)存喷众。它們的緩沖不僅存在于 java虛擬機內(nèi)各谚,還存在于java虛擬機外。如果我們僅僅是把它的引用設(shè)置為null,而不關(guān)閉它們到千,往往會造成內(nèi)存泄漏昌渤。

解決方案:

  • 程序退出時確保資源性對象已關(guān)閉;

7、集合中對象沒清理
我們通常把一些對象的引用加入到了集合容器(比如ArrayList)中憔四,當(dāng)我們不需要該對象時膀息,并沒有把它的引用從集合中清理掉般眉,這樣這個集合就會越來越大,可能會導(dǎo)致內(nèi)存泄漏潜支。如果這個集合是static的話甸赃,那情況就更嚴(yán)重了。

解決方案:

  • 在Activity退出之前冗酿,將集合里的東西clear埠对,然后置為null,再退出程序裁替;

8项玛、WebView對象沒有回收
不再使用WebView對象時,應(yīng)該調(diào)用它的destory()函數(shù)來銷毀它弱判,并釋放其占用的內(nèi)存襟沮,否則其占用的內(nèi)存長期也不能被回收,從而造成內(nèi)存泄露裕循。

解決方案:

  • 為webView開啟另外一個進程臣嚣,通過AIDL與主線程進行通信,WebView所在的進程可以根據(jù)業(yè)務(wù)的需要選擇合適的時機進行銷毀剥哑,從而達到內(nèi)存的完整釋放

9硅则、構(gòu)造Adapter時,沒有使用緩存的ConvertView
初始時ListView會從Adapter中根據(jù)當(dāng)前的屏幕布局實例化一定數(shù)量的View對象株婴,同時ListView會將這些View對象 緩存起來怎虫。

當(dāng)向上滾動ListView時,原先位于最上面的List Item的View對象會被回收困介,然后被用來構(gòu)造新出現(xiàn)的最下面的List Item大审。

這個構(gòu)造過程就是由getView()方法完成的,getView()的第二個形參View ConvertView就是被緩存起來的List Item的View對象(初始化時緩存中沒有View對象則ConvertView是null)座哩。

參考資料:
內(nèi)存泄露和內(nèi)存溢出(OOM)的引發(fā)原因及優(yōu)化方案

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末徒扶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子根穷,更是在濱河造成了極大的恐慌姜骡,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屿良,死亡現(xiàn)場離奇詭異圈澈,居然都是意外死亡,警方通過查閱死者的電腦和手機尘惧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門康栈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事啥么〉俏瑁” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵悬荣,是天一觀的道長逊躁。 經(jīng)常有香客問我,道長隅熙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任核芽,我火速辦了婚禮囚戚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘轧简。我一直安慰自己驰坊,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布哮独。 她就那樣靜靜地躺著拳芙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪皮璧。 梳的紋絲不亂的頭發(fā)上舟扎,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音悴务,去河邊找鬼睹限。 笑死,一個胖子當(dāng)著我的面吹牛讯檐,可吹牛的內(nèi)容都是我干的羡疗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼别洪,長吁一口氣:“原來是場噩夢啊……” “哼叨恨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挖垛,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤痒钝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后晕换,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體午乓,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年闸准,在試婚紗的時候發(fā)現(xiàn)自己被綠了益愈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蒸其,靈堂內(nèi)的尸體忽然破棺而出敏释,到底是詐尸還是另有隱情,我是刑警寧澤摸袁,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布钥顽,位于F島的核電站,受9級特大地震影響靠汁,放射性物質(zhì)發(fā)生泄漏蜂大。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一蝶怔、第九天 我趴在偏房一處隱蔽的房頂上張望奶浦。 院中可真熱鬧,春花似錦踢星、人聲如沸澳叉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽成洗。三九已至,卻和暖如春藏否,著一層夾襖步出監(jiān)牢的瞬間瓶殃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工副签, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碌燕,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓继薛,卻偏偏與公主長得像修壕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子遏考,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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

  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問題慈鸠。內(nèi)存泄漏...
    _痞子閱讀 1,625評論 0 8
  • 內(nèi)存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問題。內(nèi)存泄漏大家都不陌生了灌具,簡單粗俗的講青团,...
    宇宙只有巴掌大閱讀 2,360評論 0 12
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,510評論 25 707
  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問題。內(nèi)存泄漏...
    apkcore閱讀 1,217評論 2 7
  • 是一個寫作類的app咖楣,界面很好看 試一試督笆。 孤獨太沉重,寫點東西诱贿,會釋然很多娃肿。
    可抑閱讀 198評論 0 0