天天看點

記錄一次Android記憶體洩漏事件和解決過程

昨天打算在車機上測一下長時間跑LogWatcher會不會出問題,跑了一上午之後果然出問題了,程式發生了ANR,然後就在Android studio上看了看程式占用的記憶體,我靠,居然占用了一百多M,這還了得。我當時掐指一算,肯定是發生了記憶體洩漏。随後我便重新運作了程式,然後一直覺察程式的記憶體變化。果然讓我發現了端倪,程式GC的頻率很高,并且每一次GC之後,程式占用的記憶體都會有小的增幅。這代表什麼,這不就是程式一直在增加無用的東西,并且不能被GC回收掉嗎。由于以前從來沒遇到過OOM的問題,都不知道如何下手,開始沒頭緒的亂改,毫無效果,最後還是沉下心在網上看了幾篇記憶體洩漏分析的文章,最後終于解決了這個問題。

現在總結出來發生記憶體洩漏的幾個常見因素:

1、BitMap相關,BitMap占用大量記憶體并且沒有正确回收,但是我的程式沒用到BitMap啊,排除這條。

2、activity相關,大多是activity的Context對象一直被外部某個對象持有,造成無法正常完成聲明周期進行回收,不過我的程式主界面根本就不會回收,除非退出程式,是以也排除這條。

3、奢侈的資源未關閉造成的記憶體洩漏,對于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等這些資源的使用,一定要注意回收的方式,不是僅僅将對象置為空就行的。我發現我的OutputStream的成員變量一直都在new 但是在new之前并沒有close,然後我在每次new之前都添加判空條件,如果不為空則先執行close。

對于出現記憶體洩漏問題,光看代碼是不夠的,還是需要工具去分析一下,我用的就是Eclipse Memory Analyzer,也就是MAT。因為MAT我也是第一次用,也沒有什麼經驗,如果想了解,這篇文章寫得挺詳細,解釋的挺明白 http://tivan.iteye.com/blog/1487855

這是我用MAT得到的圖

記錄一次Android記憶體洩漏事件和解決過程

這裡看到ArrayList占用了2.4M的記憶體,然後我就點進去看

記錄一次Android記憶體洩漏事件和解決過程

然後我就在那個類裡面找到了那段代碼,到這裡分析就結束了,不得不說記憶體分析真是個考驗耐心的活,不靜下心來真是很難發現代碼中的端倪。最後附上一個Android記憶體洩漏分析的總結連接配接 https://yq.aliyun.com/articles/3009 

繼續閱讀