內(nèi)存泄漏原因
根據(jù)gc回收機(jī)制毛仪,已銷毀的組件或?qū)ο筮€被引用搁嗓,導(dǎo)致無(wú)法被回收,導(dǎo)致內(nèi)存泄漏箱靴,內(nèi)存占用將越來(lái)越多腺逛,而虛擬機(jī)為每個(gè)App分配內(nèi)存是有限的,最終內(nèi)存溢出衡怀。
1棍矛,Application引用Activity,Application的生命周期是整個(gè)App的周期狈癞,如果引用某一個(gè)Activity實(shí)例茄靠,將導(dǎo)致Activity組件銷毀時(shí)茂契,對(duì)象無(wú)法回收蝶桶。
2,匿名內(nèi)部類掉冶,非靜態(tài)內(nèi)部類真竖,他們會(huì)持有外部類對(duì)象的引用脐雪。在Activity中定義的,導(dǎo)致無(wú)法回收恢共。如Handler消息隊(duì)列有未處理消息但是Activity已經(jīng)銷毀战秋,導(dǎo)致泄漏,靜態(tài)或弱引用解決讨韭。還有Thread脂信,以及AsyncTask。
3透硝,static修飾的變量引用Activity狰闪,同理,static的生命周期是整個(gè)app的周期濒生。
4埋泵,單例模式,生命周期與app相同罪治,導(dǎo)致泄漏丽声。
5,資源未關(guān)閉觉义,造成的內(nèi)存泄漏雁社,如file,curse晒骇,stream歧胁,在finally中close關(guān)閉資源對(duì)象,厉碟。
6喊巍,Activity內(nèi)部創(chuàng)建一個(gè)靜態(tài)對(duì)象,構(gòu)造方法包含Context箍鼓,使用this傳入創(chuàng)建崭参。
7,WebView內(nèi)存泄漏款咖。未unregister何暮,callback。先移除view铐殃,在destory海洼。解決方案可以開(kāi)啟一個(gè)獨(dú)立進(jìn)程,aidl和主進(jìn)程通信富腊。
8坏逢,容器對(duì)象未清理,將引用從集合中清除掉。
9是整,注冊(cè)對(duì)象未注銷肖揣。如BraodcastReceiver注冊(cè)。
Handler導(dǎo)致內(nèi)存泄漏
Handler綁定主線程消息隊(duì)列和Looper浮入,同時(shí)龙优,內(nèi)部匿名Handelr定義會(huì)持有外部Activity的實(shí)例,在這種情況下事秀,如果我們通過(guò)Handler發(fā)送了一個(gè)延遲幾分鐘的消息到主線程消息隊(duì)列彤断,銷毀Activity。
因?yàn)橄⒁呀?jīng)放在主線程消息隊(duì)列易迹,消息隊(duì)列由主線程一直在處理瓦糟,肯定不會(huì)被回收,而剛才的消息被插入到隊(duì)列中赴蝇,還有一定時(shí)間才會(huì)處理菩浙,也不會(huì)被回收,同時(shí)句伶,消息中拿著該Handler的引用劲蜻,即target,這個(gè)是關(guān)鍵考余,Handler也不會(huì)被回收先嬉,導(dǎo)致Activity無(wú)法被回收。
解決方案:只要不持有Activity的強(qiáng)引用即可楚堤。
1疫蔓,靜態(tài)內(nèi)部類+弱引用。
2身冬,外部類定義Handler衅胀。
3,結(jié)束Activity時(shí)酥筝,將消息移除隊(duì)列滚躯,切斷了和消息隊(duì)列的關(guān)系,這樣msg即可以被gc嘿歌,那么handler也會(huì)掸掏。
內(nèi)存分析工具
1,直接在As查看內(nèi)存分配情況宙帝,操作應(yīng)用時(shí)丧凤,內(nèi)存一直往上漲說(shuō)明存在內(nèi)存泄露。
2步脓,內(nèi)存泄露分析工具M(jìn)AT(Memory Analyzer tool)愿待。
3浩螺,LeakCanary快速定位內(nèi)存泄露。
Android Profiler
監(jiān)控應(yīng)用內(nèi)存呼盆,cpu和網(wǎng)絡(luò)的圖形化工具,可以顯示可用/已用內(nèi)存蚁廓。
內(nèi)存監(jiān)控Memory Profiler整合了Heap Viewer访圃,Allocation Tracker和Memory Monitor的特性,可以觀察對(duì)象分配實(shí)時(shí)數(shù)量相嵌,觀察一段時(shí)間內(nèi)的垃圾收集事件腿时,F(xiàn)orce GC,Dump Java heap饭宾。
Heap Viewer
5.0及以上的系統(tǒng)批糟,查看所有內(nèi)存情況,手動(dòng)GC看铆。
Heap Size徽鼎,堆棧分配App的內(nèi)存大小,Allocated弹惦,使用大小否淤,F(xiàn)ree,空閑大小棠隐,Used石抡,使用率,Object助泽,對(duì)象數(shù)量啰扛。
展現(xiàn)所有數(shù)據(jù)類型的內(nèi)存情況。
Allocation Tracker
分配跟蹤記錄App的內(nèi)存分配嗡贺,列出調(diào)用堆棧隐解,查看所有對(duì)象內(nèi)存分配周期。
啟動(dòng)Allocation Tracking诫睬,操作App厢漩,結(jié)束追蹤。生成alloc文件岩臣,記錄此次追蹤到的所有內(nèi)存數(shù)據(jù)溜嗜。Android Stuido可打開(kāi)此文件查看。
任重而道遠(yuǎn)