Android中的記憶體洩漏
1.什麼事記憶體洩漏
記憶體不在GC的掌控之中了
本來應該回收的物件,還存留在記憶體中,
(1)什麼是GC(垃圾回收機制)?
某物件不再有任何的任何的引用的時候才會進行回收,舉例(餐廳餐具回收),
延伸:GC回收機制的原理,深入的話去了解JVM虛擬機器
(GC ROOT TRACING回收演算法)
GC動作發生的時候,從一個GCROOT物件開始往下走,找到一個物件是被GCROOT物件所持有,那麼久不會回收,以此類推,只要持有就不會回收,找到沒有被引用的物件,就會標記為允許被回收的,例外情況,就是記憶體洩露了.
①可以被GCROOT物件引用的點是哪些?在JAVA STACK中引用的物件
在方法區中靜態引用指向的物件
方法區中常量引用指向的物件
Native方法中JNI引用的物件
活著的Thread
②怎麼判斷一個物件是垃圾物件
垃圾物件就是沒有被引用嗎,no,沒有被引用是可以回收的,這是一個主觀判斷,假設我們new了一個物件,然後退出了程式,去記憶體中檢視,那這個物件也是垃圾物件,在GC眼裡這不是垃圾物件,但是在我們眼裡,這就是垃圾物件,
2.確定專案中存在記憶體洩漏
粗略判斷AndroidMonitor--System Infomations---Activity.View等數量是否為0
3.確定記憶體洩漏在哪兒
(1)AndroidStudioMemoryMonitor工具
(2)粗略估計不行的話,可以生成hprof檔案,用記憶體分析工具來分析,例如MAT,LeakCanary
4.常見的記憶體洩漏
記憶體洩漏產生的原因在Android中大致分為以下幾種:原部落格地址
(1).static變數引起的記憶體洩漏
因為static變數的生命週期是在類載入時開始 類解除安裝時結束,也就是說static變數是在程式程式死亡時才釋放,如果在static變數中 引用了Activity 那麼 這個Activity由於被引用,便會隨static變數的生命週期一樣,一直無法被釋放,造成記憶體洩漏。
解決辦法:
在Activity被靜態變數引用時,使用 getApplicationContext 因為Application生命週期從程式開始到結束,和static變數的一樣。
(2).執行緒造成的記憶體洩漏
類似於上述例子中的情況,執行緒執行時間很長,及時Activity跳出還會執行,因為執行緒或者Runnable是Acticvity內部類,因此握有Activity的例項(因為建立內部類必須依靠外部類),因此造成Activity無法釋放。
AsyncTask 有執行緒池,問題更嚴重
解決辦法:
1.合理安排執行緒執行的時間,控制執行緒在Activity結束前結束。
2.將內部類改為靜態內部類,並使用弱引用WeakReference來儲存Activity例項 因為弱引用 只要GC發現了 就會回收它 ,因此可儘快回收
(3).BitMap佔用過多記憶體
bitmap的解析需要佔用記憶體,但是記憶體只提供8M的空間給BitMap,如果圖片過多,並且沒有及時 recycle bitmap 那麼就會造成記憶體溢位。
解決辦法:
及時recycle 壓縮圖片之後載入圖片
(4).資源未被及時關閉造成的記憶體洩漏
比如一些Cursor 沒有及時close 會儲存有Activity的引用,導致記憶體洩漏
解決辦法:
在onDestory方法中及時 close即可
(5).Handler的使用造成的記憶體洩漏
由於在Handler的使用中,handler會傳送message物件到 MessageQueue中 然後 Looper會輪詢MessageQueue 然後取出Message執行,但是如果一個Message長時間沒被取出執行,那麼由於 Message中有 Handler的引用,而 Handler 一般來說也是內部類物件,Message引用 Handler ,Handler引用 Activity 這樣 使得 Activity無法回收。
解決辦法:
依舊使用 靜態內部類+弱引用的方式 可解決
(6).帶引數的單例
5.專案中的例子
(1)原來寫香信OA的時候,實現Banner滾動區域,使用了Thread的方法,while迴圈每隔五秒跳一下,------
(2)CIvetIM中,RxBus註冊的例子,
(3)==
相關文章
- Android中的記憶體洩漏模式Android記憶體模式
- Android 記憶體洩漏Android記憶體
- Android記憶體洩漏Android記憶體
- Android中常見的記憶體洩漏Android記憶體
- Android記憶體洩漏場景Android記憶體
- Android備忘錄《記憶體洩漏》Android記憶體
- 初步探究Android記憶體洩漏(1)Android記憶體
- vue使用中的記憶體洩漏Vue記憶體
- [譯] Swift 中的記憶體洩漏Swift記憶體
- Android 輕鬆解決記憶體洩漏Android記憶體
- Android常見記憶體洩漏總結Android記憶體
- Android Handler機制之記憶體洩漏Android記憶體
- 分析記憶體洩漏和goroutine洩漏記憶體Go
- 記憶體洩漏的原因記憶體
- 如何避免JavaScript中的記憶體洩漏?JavaScript記憶體
- jvm 記憶體洩漏JVM記憶體
- Java記憶體洩漏Java記憶體
- js記憶體洩漏JS記憶體
- 小心遞迴中記憶體洩漏遞迴記憶體
- Android效能優化篇之記憶體優化--記憶體洩漏Android優化記憶體
- 每日一問:Android 中記憶體洩漏都有哪些注意點?Android記憶體
- WebView引起的記憶體洩漏WebView記憶體
- [譯]理解閉包中的記憶體洩漏記憶體
- 翻譯 | 理解Java中的記憶體洩漏Java記憶體
- JavaScript中的垃圾回收和記憶體洩漏JavaScript記憶體
- 如何檢查Javascript中的記憶體洩漏JavaScript記憶體
- Java應用程式中的記憶體洩漏及記憶體管理Java記憶體
- valgrind 記憶體洩漏分析記憶體
- 記憶體的分配與釋放,記憶體洩漏記憶體
- Android記憶體洩漏檢測與修復技巧Android記憶體
- Android Native 記憶體洩漏系統化解決方案Android記憶體
- Android中使用Handler為何造成記憶體洩漏?Android記憶體
- 【記憶體洩漏和記憶體溢位】JavaScript之深入淺出理解記憶體洩漏和記憶體溢位記憶體溢位JavaScript
- JVM——記憶體洩漏與記憶體溢位JVM記憶體溢位
- .NET 記憶體洩漏的爭議記憶體
- Swift的ARC和記憶體洩漏Swift記憶體
- 定位並修復 Go 中的記憶體洩漏Go記憶體
- 記憶體洩漏除錯工具記憶體除錯
- ThreadLocal真會記憶體洩漏?thread記憶體