Android檢測記憶體洩漏之leakcanary
記憶體洩漏,memory leak,開發者經常唸叨的一個詞,稍不留意,就遊走在我們的程式碼中。Andriod開發,記憶體洩漏的原因有很多,比如activity的context引用,static引用,廣播未取消註冊,MVP設計時沒有detachView,Rx沒有取消subscribe訂閱,動畫處理等。檢測的工具也很多。今天總結下,LeakCanary的使用。看這圖,Js介面引用activity洩漏了528kb。
一,大話記憶體洩漏
Java通過垃圾收集器(GC, garbage collection)來自動管理記憶體。當一個物件不再被使用,就會被自動回收。而“記憶體洩漏“就是沒有成功回收記憶體的體現。一個物件已經不需要再使用了,但是因為其它的物件持有該物件的引用,導致它的記憶體不能被回收。“記憶體洩漏”積累到一定程度,可能導致OOM,所以在寫程式碼的過程中,要注意導致“記憶體洩漏”的程式碼寫法,提高程式碼的健壯性。
二,記憶體洩漏的型別
如果一個物件是可達的有引用的,但實際上它已經沒有再使用了,但引用它的物件依然存在,這樣的它就是記憶體洩漏的物件。記憶體洩漏可分為以下幾種型別:
1、靜態變數引起的記憶體洩漏
通常是,一個靜態變數,持有物件的應用,物件銷燬了,static修飾的變數還在,導致記憶體無法回收。我之前在BaseActivity中加入實現類到集合中,就造成過記憶體洩漏。如過靜態context一直持有activity的引用,onDestory執行後造成記憶體洩漏。
public class LeakActivity extends Activity {
//靜態context
private static Context sContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_leak);
sContext = this;//賦值後靜態context一直持有activity的引用,onDestory執行後造成記憶體洩漏。
}
}
我遇到的情況,activity當上下文傳,js介面引用webview所在的activity,反正不要靜態的引用。
2、非靜態內部類引起的記憶體洩漏
如果用android studio開發,寫handle傳送訊息,下面的寫法會有黃色警告,因為可能會引發記憶體洩漏:
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
為什麼呢?非靜態內部類會引用外部類物件(Activity),當它使用了 postDelayed 的時候,如果 Activity 已經 finish 了,而這個 handler 仍然引用著這個 Activity 就會致使記憶體洩漏,因為這個 handler 會在一段時間內繼續被 mainLooper 持有,導致引用仍然存在,在這段時間內,如果記憶體不夠使,可能OOM了。
3、資源未關閉引起的記憶體洩漏
IO流的操作,切記要close關閉流,檔案讀寫,網路訪問等都要及時關閉位元組流、字元流;註冊了廣播要在onDestory方法中銷燬。使用了BraodcastReceiver、Cursor、Bitmap等資源時,需要及時釋放掉,若沒有釋放,則會引起記憶體洩漏。這個比較好理解。
三,記憶體洩漏檢測工具
用Eclipse開發自帶的記憶體檢測工具:Heap。
DDMS中的Heap工具用於大致分析是否存在“記憶體洩漏”,而MAT工具則用於分析“記憶體洩漏”發生在哪裡,MAT工具中,File->Open Heap Dump,可以開啟xxx.hprof檔案分析。這個我現在不用。不多說。直接看下面介紹的LeakCanary。
四,LeakCanary,記憶體洩漏精確檢測神器。
要精確地追蹤到記憶體洩漏點,強烈推薦使用Square 公司開源的 LeakCanary開源方案,LeakCanary在Application實現類中一行程式碼,簡單暴力侵入性地捕獲記憶體洩漏程式碼,甚至捕獲Android元件的記憶體洩漏程式碼。我發現android動畫繪製的時候存在記憶體洩漏的問題。
1,LeakCanary就像金絲雀監視著你的“煤礦”
不用重複造輪子,直接拿來,android studio開擼步驟:
//在module的build.gradle中:
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
//上面是官方推薦寫法,其實你要一行也行:
compile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
//然後在你的Application的子類中install:
public class ExampleApplication extends Application{
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
Good,好了,LeakCanary這是金絲雀會隨著你app的執行,自動安裝監測,給你通知。方便你檢視那個類出現了記憶體洩漏,甚至告訴你洩漏了多少M。如圖:
2,檢視log日誌,分析LeakCanary收集的資料
一般通過它的通知介面就很明瞭了,如果要詳細看看過程,看log部分如下:SplashActivity has leaked!
五,總結
遇到記憶體洩漏不是什麼好事,所以平時寫程式碼,留個心眼,以預防為主。一些通用的解決方案:
1,使用Application的context
需要上下文的時候,如果不是非得activity物件,傳入Application的context,因為Application的context的生命週期比Activity長,它是app全域性的,相當於static的生命週期。
2,static變數不要引用view例項
3,關閉資源,close,unsubscribe,unregister,null記得吃藥。
歡迎交流,Dusan,杜乾,291902259!OpenDeveloper!
相關文章
- Android 記憶體洩漏檢測工具 LeakCanary(Kotlin版)的實現原理Android記憶體Kotlin
- iOS檢測記憶體洩漏iOS記憶體
- 如何檢測記憶體洩漏記憶體
- JavaScript記憶體洩漏檢測工具JavaScript記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(上)Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(下)Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(中)Android優化記憶體
- 007 LeakCanary 記憶體洩漏原理完全解析記憶體
- LeakCanary 傻瓜式的記憶體洩露檢測工具記憶體洩露
- LeakCanary傻瓜式的記憶體洩露檢測工具記憶體洩露
- 使用 Instruments 檢測記憶體洩漏記憶體
- MFC 檢測記憶體洩漏的方法記憶體
- 檢測並排除記憶體洩漏 (轉)記憶體
- Android 記憶體洩漏Android記憶體
- Android記憶體洩漏Android記憶體
- C++ 程式記憶體洩漏檢測方法C++記憶體
- C/C++記憶體洩漏及檢測C++記憶體
- VC++6.0中記憶體洩漏檢測C++記憶體
- Android Handler機制之記憶體洩漏Android記憶體
- Android效能優化之記憶體洩漏Android優化記憶體
- Android 記憶體洩漏分析Android記憶體
- LeakCanary(二)記憶體洩露監測原理研究記憶體洩露
- Android 檢測記憶體洩露Android記憶體洩露
- 如何在 Linux 下檢測記憶體洩漏Linux記憶體
- iOS記憶體洩漏自動檢測工具PLeakSnifferiOS記憶體
- JavaScript之記憶體洩漏【四】JavaScript記憶體
- 記憶體洩漏記憶體
- 如何檢測記憶體洩漏——過載new和delete記憶體delete
- 請教 關於記憶體洩漏的檢測方法記憶體
- Android記憶體洩漏場景Android記憶體
- Android中的記憶體洩漏Android記憶體
- Android 記憶體洩漏總結Android記憶體
- (Android Studio 3.0)Android Profiler記憶體洩漏檢查Android記憶體
- Android效能優化篇之記憶體優化--記憶體洩漏Android優化記憶體
- JavaScript之記憶體溢位和記憶體洩漏JavaScript記憶體溢位
- 【記憶體洩漏和記憶體溢位】JavaScript之深入淺出理解記憶體洩漏和記憶體溢位記憶體溢位JavaScript
- 分析記憶體洩漏和goroutine洩漏記憶體Go
- 【Java面試題】之記憶體洩漏Java面試題記憶體