解決Android記憶體洩漏;輕鬆降低100M
背景
今天發現有個App存在嚴重的記憶體洩漏問題,通過安裝LeakCanary找到大致方向,通過嚴格管理Timer、Presenter和Handler,輕鬆把它消耗的內容降低了100M。
過程
LeakCanary
LeakCanary是square公司提供的一個很好用的記憶體洩漏查詢工具,與MAT不同的是,它會在你執行App時檢查你的記憶體回收,並找到記憶體洩漏點,直接提示給你,比用MAT去分析日誌的形式更加簡單直接,不過缺點是LeakCanary的資訊不像MAT那麼多,很難查到更細微的問題。
LeakCanary的安裝過程很簡單,首先配置Gradle
然後在自定義的Application中初始化
記得在Manifest中使用自定義的Application
執行App,LeakCanary會在App執行過程中不定期收集資訊,如果發現有記憶體洩漏的問題,就會在通知欄中給出提示,如XXXActivity大概因為XXX洩露了XXM記憶體,比如我們執行LeakCanary在Github上的demo,得到的提示就會像下圖這樣
可見,直接指出了問題類和問題原因,比起MAT還是簡單多了的
Timer
在檢查中,在Presenter裡忘記關閉一個Timer的task,在Activity的onDestroy事件中呼叫Presenter的onDestroy
在Presenter的onDestroy中執行銷燬操作
我們看到,在Presenter銷燬元素時,做了三件事:
1.關閉執行緒(要先執行interrupt,否則休眠執行緒無法立即停止)
2.銷燬Presenter中關聯的View物件(否則會導致對應的Activity無法釋放)
3.退出Timer定時任務
Presenter
再看一遍Presenter執行銷燬操作的程式碼
在上圖中,我們看到Presenter在銷燬時,一定要把View銷燬掉,否則會導致對應的Activity或Fragment無法釋放,在檢查中發現有些Presenter沒有寫銷燬,考慮在以後統一實現一個Presenter的基類,在基類中實現銷燬View的程式碼
Handler
在檢查中,發現有些對話方塊彈出後無法回收記憶體,在檢查中發現了這樣的程式碼
LeakHandler
這是我們一般接觸到的典型的Handler寫法,但是注意看提示,提示中說明了這裡有洩漏風險,從避免記憶體洩漏的角度,應該改成這樣的程式碼
在這段寫法中,我們用static內部類去過載了一個Handler,static內部類實際上會生成一個弱引用物件,這就不會產生記憶體洩漏。
不過這樣一來,在static內部類中,我們就無法呼叫Activity的函式了,這就需要在這個Handler初始化時把Activity傳進來,直接傳進來的Activity還是可能造成記憶體洩漏,我們還要把它放到一個弱引用物件裡,通過get()函式取得Activity物件並呼叫其函式。
總結
在這次的記憶體洩漏查詢過程中,主要解決了三個問題
1.及時銷燬所有的Timer定時任務
2.及時銷燬Presenter中的View物件
3.檢查所有的Handler,改為static+弱引用的實現方式
解決這些問題後,再次執行LeakCanary,已經不再輸出記憶體洩漏的內容了,App消耗的記憶體也減少了100多M。
其實這裡解決的記憶體洩漏問題都是很淺顯的部分,能在這些地方出錯,說明這個App的記憶體洩漏已經相當嚴重了,在日常編碼中,還是要多留一份心才是。
附錄
Android高階技術大綱,以及系統進階視訊;
Android高階技術大綱
Android進階系統資料視訊
獲取方式;
加Android進階群;701740775。即可前往免費領取。免費備註一下csdn
相關文章
- Android 輕鬆解決記憶體洩漏Android記憶體
- Android記憶體洩漏Android記憶體
- Android 記憶體洩漏Android記憶體
- Java記憶體洩漏解決之道Java記憶體
- Android記憶體洩漏場景Android記憶體
- Handler記憶體洩漏分析及解決記憶體
- 解決記憶體洩漏(1)-ApacheKylin InternalThreadLocalMap洩漏問題分析記憶體Apachethread
- Android Native 記憶體洩漏系統化解決方案Android記憶體
- Android技術分享| Android 中部分記憶體洩漏示例及解決方案Android記憶體
- Android備忘錄《記憶體洩漏》Android記憶體
- Android中的記憶體洩漏模式Android記憶體模式
- Android中常見的記憶體洩漏Android記憶體
- 初步探究Android記憶體洩漏(1)Android記憶體
- Handler記憶體洩漏原因及解決方案記憶體
- Android Handler機制之記憶體洩漏Android記憶體
- Android常見記憶體洩漏總結Android記憶體
- 分析記憶體洩漏和goroutine洩漏記憶體Go
- 深入瞭解 JavaScript 記憶體洩漏JavaScript記憶體
- js記憶體洩漏JS記憶體
- jvm 記憶體洩漏JVM記憶體
- Java記憶體洩漏Java記憶體
- 手把手教你解決 Flutter engine 記憶體洩漏Flutter記憶體
- Handler的使用、記憶體洩漏和解決記憶體
- Android效能優化篇之記憶體優化--記憶體洩漏Android優化記憶體
- 基於Android Studio的記憶體洩漏檢測與解決全攻略Android記憶體
- 記一則伺服器記憶體洩漏解決過程伺服器記憶體
- 記憶體洩漏的原因記憶體
- valgrind 記憶體洩漏分析記憶體
- Android中使用Handler為何造成記憶體洩漏?Android記憶體
- Android記憶體洩漏檢測與修復技巧Android記憶體
- 【記憶體洩漏和記憶體溢位】JavaScript之深入淺出理解記憶體洩漏和記憶體溢位記憶體溢位JavaScript
- JVM——記憶體洩漏與記憶體溢位JVM記憶體溢位
- Android 記憶體洩露詳解Android記憶體洩露
- ThreadLocal原理用法詳解ThreadLocal記憶體洩漏thread記憶體
- iOS檢測記憶體洩漏iOS記憶體
- ThreadLocal記憶體洩漏問題thread記憶體
- PHP 記憶體洩漏分析定位PHP記憶體
- 記憶體洩漏除錯工具記憶體除錯