Android內(nèi)存泄漏筆記

實(shí)操 MAT:
androidProfile進(jìn)行headdump

命令行導(dǎo)出快照

然后MAT進(jìn)行配對

原理:
GC回收機(jī)制,某對象不再持有任何的引用的時候才會回收
問:如果某對象被別的對象引用了,就不能被GC回收
否,軟引用、虛引用、弱引用——》用來避免內(nèi)存過度消耗以及容易內(nèi)存泄漏的
該對象一直往上追溯引用,能追溯到GC Root 引用點(diǎn)才能說不被GC回收

可以作為GC Root 引用點(diǎn)的:(產(chǎn)生內(nèi)存泄漏)
JAVAStack中引用的對象
方法區(qū)中的靜態(tài)引用指向?qū)ο?br> 方法區(qū)常量引用指向的對象
Native方法中JNI引用的對象
Tread--活著的對象

例子
1.單例導(dǎo)致內(nèi)存泄漏
單例模式中的靜態(tài)方法使用 Context,會導(dǎo)致靜態(tài)單例會繼續(xù)持有Activity引用,導(dǎo)致無法釋放

   //修改
   context = context.getApplicationContext();

2.靜態(tài)變量導(dǎo)致內(nèi)存泄露
生命周期不一致導(dǎo)致內(nèi)存泄漏
優(yōu)化修改:
進(jìn)行少的使用,或者在適當(dāng)?shù)奈恢弥刂脼閚ull

3.非靜態(tài)內(nèi)部類導(dǎo)致內(nèi)存泄露
Handler、Thread、AsyncTask
msg持有Handler,mHandler 會作為成員變量保存在發(fā)送的消息 msg 中,msg就間接持有Activity,導(dǎo)致Activity推出后,Looper還是在輪詢,導(dǎo)致無法釋放Activity,進(jìn)而引起內(nèi)存泄漏。
最后別忘了mHandler.removeCallbacksAndMessages。
優(yōu)化修改:

private static class MyHandler extends Handler {
private WeakReference<MainActivity> activityWeakReference;
public MyHandler(MainActivity activity) { 
activityWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = activityWeakReference.get(); 
if (activity != null) {
if (msg.what == 1) { // 做相應(yīng)邏輯
    } }
   }}
}

4.未取消注冊或回調(diào)導(dǎo)致內(nèi)存泄露
例如廣播和Retrofit+RxJava
5.Timer 和 TimerTask 導(dǎo)致內(nèi)存泄露
cancel 掉 Timer 和 TimerTask
6.集合中的對象未清理造成內(nèi)存泄露
7.資源未關(guān)閉或釋放導(dǎo)致內(nèi)存泄露
8.屬性動畫造成內(nèi)存泄露
9.WebView 造成內(nèi)存泄露

總結(jié):
構(gòu)造單例的時候盡量別用 Activity 的引用;
靜態(tài)引用時注意應(yīng)用對象的置空或者少用靜態(tài)引用;
使用靜態(tài)內(nèi)部類+軟引用代替非靜態(tài)內(nèi)部類;
及時取消廣播或者觀察者注冊;
耗時任務(wù)、屬性動畫在 Activity 銷毀時記得 cancel;
文件流、Cursor 等資源及時關(guān)閉;
Activity 銷毀時 WebView 的移除和銷毀。

參考:
網(wǎng)易
MAT 下載地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容