Android內(nèi)存泄露 一篇文章就夠了

本文整理了市面上現(xiàn)有的所有內(nèi)存泄露文章黔衡,加上個(gè)人理解進(jìn)行歸納總結(jié)

描述

內(nèi)存泄露簡(jiǎn)單說(shuō)就是已經(jīng)沒(méi)有用的資源秕磷,但是由于被其他資源引用著

無(wú)法被GC銷毀纯露。

危害

內(nèi)存泄露是內(nèi)存溢出OOM的重要原因之一乖菱,會(huì)導(dǎo)致Crash

如果應(yīng)用程序在消耗光了所有的可用堆空間(16M到48M)静陈,那么再試圖在堆上分配新對(duì)象時(shí)就會(huì)引起OOM(Out Of Memory Error)異常,此時(shí)應(yīng)用程序就會(huì)崩潰退出螟碎。

現(xiàn)在的手機(jī)內(nèi)存越來(lái)越大眉菱,小的內(nèi)存泄漏并不會(huì)有太大危害,但是我們是有夢(mèng)想的程序員掉分,我們想要做出精致的APP俭缓。

檢測(cè)工具

Leaks

https://github.com/square/leakcanary

傻瓜式的內(nèi)存檢測(cè)工具,但是非常好用

當(dāng)然我們可以用AS Monitor+MAT來(lái)自己分析內(nèi)存泄漏原因

http://www.2cto.com/kf/201512/455421.html


從根本上解釋內(nèi)存泄露原因

前文已經(jīng)提到了GC Roots酥郭,內(nèi)存泄露就是因?yàn)閮?nèi)存泄露簡(jiǎn)單說(shuō)就是已經(jīng)沒(méi)有用的資源华坦,但是由于最終被GC Roots引用著無(wú)法被GC銷毀。

Google官方的兩張圖不从,方便理解惜姐,最終藍(lán)色的資源就會(huì)被回收


Gc 檢測(cè)流程1


Gc 檢測(cè)流程2

那么都有哪些資源是GC Roots呢?

1.Class 由System Class Loader/Boot Class Loader加載的類椿息,這些類不會(huì)被回收歹袁。注意是類不會(huì)被回收,實(shí)例還是會(huì)被回收的寝优,但是不依賴實(shí)例的靜態(tài)static變量是依賴類的条舔,因此很多內(nèi)存泄露都是因?yàn)楸混o態(tài)變量引用導(dǎo)致的。

2.Thread 線程乏矾,激活狀態(tài)的線程逞刷;

3.Stack Local 棧中的對(duì)象。每個(gè)線程都會(huì)分配一個(gè)棧妻熊,棧中的局部變量或者參數(shù)都是GC root夸浅,因?yàn)樗鼈兊囊秒S時(shí)可能被用到;

4.JNI Local JNI中的局部變量和參數(shù)引用的對(duì)象扔役;可能在JNI中定義的帆喇,也可能在虛擬機(jī)中定義

5.JNI Global JNI中的全局變量引用的對(duì)象;同上

6.Monitor Used 用于保證同步的對(duì)象亿胸,例如wait()坯钦,notify()中使用的對(duì)象、鎖等侈玄。

7.Held by JVM JVM持有的對(duì)象婉刀。JVM為了特殊用途保留的對(duì)象,它與JVM的具體實(shí)現(xiàn)有關(guān)序仙。比如有System Class Loader, 一些Exceptions對(duì)象突颊,和一些其它的Class Loader。對(duì)于這些類,JVM也沒(méi)有過(guò)多的信息律秃。

也就是說(shuō)所有的內(nèi)存泄漏問(wèn)題從根本上都是因?yàn)楸贿@些GC Root引用著導(dǎo)致的


常見問(wèn)題

1.非靜態(tài)內(nèi)部類爬橡,匿名內(nèi)部類

2.Thread

3.ContentObserver,F(xiàn)ile棒动,Cursor糙申,Stream,Bitmap等資源未關(guān)閉

4.Webview

5.BraodcastReceiver船惨,EventBus等觀察者注冊(cè)未注銷

處理原則

1.內(nèi)部類靜態(tài)化柜裸,內(nèi)部類里面的資源及時(shí)關(guān)閉不要靜態(tài)化

2.注意線程的及時(shí)關(guān)閉

3.注意資源的及時(shí)關(guān)閉

4.webView單獨(dú)開線程(下面有具體的例子)

5.同樣需要及時(shí)關(guān)閉

自己遇到的內(nèi)存泄露問(wèn)題

一. 單例或一些靜態(tài)資源導(dǎo)致內(nèi)存泄漏(影響較小)

1.InputMethodManager

主要是Android OS遺留的問(wèn)題

google官方確認(rèn)問(wèn)題

https://code.google.com/p/android/issues/detail?id=171190

因?yàn)镮nputMethodManager是單例粱锐,即使泄露也不會(huì)有有很大影響粘室,建議忽略

當(dāng)然也有解決方案

leaks上給的鏈接

https://gist.github.com/pyricau/4df64341cc978a7de414

親測(cè)6.0沒(méi)生效

http://www.reibang.com/p/aa2555628b17親測(cè)生效

2.單例Dialog(或則單例View)

一直保有Context引用,銷毀不了

解決方法就是不用單例了卜范,讓各個(gè)Activity new就可以了

二. 注冊(cè)監(jiān)聽廣播等沒(méi)有注銷(影響較大)

1.RXBUS EventBus等注冊(cè)監(jiān)聽之后沒(méi)有注銷,導(dǎo)致內(nèi)存泄漏

一直保有Context引用鹿榜,銷毀不了

解決方案就是頁(yè)面銷毀是注銷監(jiān)聽

三.WebView內(nèi)存泄露(影響較大)

解決方案是用新的進(jìn)程起含有WebView的Activity

并且在該Activity 的onDestory() 最后加上 System.exit(0); 殺死當(dāng)前進(jìn)程海雪。

微信也是這么做的

下面是一些webView常見問(wèn)題總結(jié)

http://www.cnblogs.com/olartan/p/5713013.html

四.匿名內(nèi)部類(影響較小)

我們這個(gè)問(wèn)題是沒(méi)有應(yīng)用到contex但是卻引用到了

暫時(shí)沒(méi)有好的解決方案舱殿,主要是內(nèi)部類需要提供一些注銷等方法


怎樣避免內(nèi)存泄露

1.使用靜態(tài)變量的時(shí)候要小心奥裸,尤其要注意Activity/Service等大對(duì)象的傳值。在單例模式中能用ApplicationContext的都用ApplicationContext沪袭,或者把聚合關(guān)系改成依賴關(guān)系湾宙,不在單例對(duì)象中持有Context引用;

2.養(yǎng)成良好的代碼習(xí)慣冈绊。注冊(cè)/反注冊(cè)要成對(duì)出現(xiàn)侠鳄,Activity和Service對(duì)象中避免使用非靜態(tài)內(nèi)部類/匿名內(nèi)部類,除非十分清楚引用關(guān)系死宣;

3.使用多線程的時(shí)候留意線程存活時(shí)間伟恶。盡量將聚合關(guān)系改成依賴關(guān)系,減少線程對(duì)象持有大對(duì)象的時(shí)間毅该;

4.在使用xxxStream,SqlLiteDatabase,Cursor類的時(shí)候要注意釋放資源博秫。使用Timer,TimerTask的時(shí)候要記得取消任務(wù)。Bitmap在使用結(jié)束后要記得recycler()眶掌。

官方推薦:

In summary, to avoid context-related memory leaks, remember the following:

1.Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)

2.Try using the context-application instead of a context-activity

3.Avoid non-static inner classes in an activity if you don’t control their life cycle, use a static inner class and make a weak reference to the activity inside

And remember that a garbage collector is not an insurance against memory leaks. Last but not least, we try to make such leaks harder to make happen whenever we can.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挡育,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子朴爬,更是在濱河造成了極大的恐慌即寒,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蒿叠,居然都是意外死亡明垢,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門市咽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)痊银,“玉大人,你說(shuō)我怎么就攤上這事施绎∷莞铮” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵谷醉,是天一觀的道長(zhǎng)致稀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)俱尼,這世上最難降的妖魔是什么抖单? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮遇八,結(jié)果婚禮上矛绘,老公的妹妹穿的比我還像新娘。我一直安慰自己刃永,他們只是感情好货矮,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斯够,像睡著了一般囚玫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上读规,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天抓督,我揣著相機(jī)與錄音,去河邊找鬼束亏。 笑死本昏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的枪汪。 我是一名探鬼主播涌穆,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼雀久!你這毒婦竟也來(lái)了宿稀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赖捌,失蹤者是張志新(化名)和其女友劉穎祝沸,沒(méi)想到半個(gè)月后矮烹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罩锐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年奉狈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涩惑。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仁期,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出竭恬,到底是詐尸還是另有隱情跛蛋,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布痊硕,位于F島的核電站赊级,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏岔绸。R本人自食惡果不足惜理逊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盒揉。 院中可真熱鬧晋被,春花似錦、人聲如沸预烙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扁掸。三九已至,卻和暖如春最域,著一層夾襖步出監(jiān)牢的瞬間谴分,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工镀脂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牺蹄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓薄翅,卻偏偏與公主長(zhǎng)得像沙兰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子翘魄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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

  • 內(nèi)存管理的目的就是讓我們?cè)陂_發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問(wèn)題鼎天。內(nèi)存泄漏大家都不陌生了,簡(jiǎn)單粗俗的講暑竟,...
    宇宙只有巴掌大閱讀 2,361評(píng)論 0 12
  • 一斋射、基礎(chǔ)知識(shí) 1、什么是內(nèi)存泄露 java中的內(nèi)存泄露是指一個(gè)無(wú)用對(duì)象持續(xù)占有內(nèi)存或無(wú)用對(duì)象的內(nèi)存得不到及時(shí)的釋放...
    LiveMoment閱讀 4,421評(píng)論 0 20
  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們?cè)陂_發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問(wèn)題。內(nèi)存泄漏...
    _痞子閱讀 1,626評(píng)論 0 8
  • 被文同時(shí)發(fā)布在CSDN上罗岖,歡迎查看涧至。 APP內(nèi)存的使用,是評(píng)價(jià)一款應(yīng)用性能高低的一個(gè)重要指標(biāo)桑包。雖然現(xiàn)在智能手機(jī)的內(nèi)...
    大圣代閱讀 4,807評(píng)論 2 54
  • 歌曲<<時(shí)間都去哪兒了>> 程磊是一個(gè)自私南蓬、卑鄙、花心的人捡多。他在廣告公司依靠著出賣朋友蓖康,剽竊別人的作品,勾引老板...
    老蔣689閱讀 1,013評(píng)論 19 57