簡述
簡單說一下內(nèi)存泄漏,總結(jié)就是該回收的沒回收
java的JVM和android的DVM以及ART都是使用的可達(dá)性分析算法或者叫根搜索算法,就是說從根對象集合(GC Roots)開始搜索,能搜索到都屬于不能清除的對象,其他的都可以定義為垃圾。
(1) Handler
引發(fā)原因
Handler發(fā)送的Message對象持有Handler的引用(可以去Message看源碼-Handler target屬性),如果我們在定義Handler的時候使用的是匿名方法的方式
Handler handler= new Handler(){public void handleMessage(Message msg) {}} ;
而且沒有使用static修飾,內(nèi)部方法會持有該類的引用(一般是Activity),只有這樣你才能方便的調(diào)用Activity當(dāng)中的View等屬性。
但這時候activity被干掉了,Handler由于還被Message持有,無法被回收,而Handler又持有Activity的引用,導(dǎo)致整個鏈條都無法回收,Activity對象很大,占用內(nèi)存空間大,而且還可能關(guān)聯(lián)很多其他的引用(比如調(diào)用的接口請求),導(dǎo)致整個鏈條都無法回收,次數(shù)多了,達(dá)到內(nèi)存上限就會OOM。
解決方法
(1)Handler定義為static的內(nèi)部類(2)使用弱引用
private static class MyHandler extends Handler {
private WeakReference<Activity> weakAct;
public MyHandler(Activity act) {weakAct= new WeakReference<>(act);}
@Override
? public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
? ? ? ? ? ? if ( weakAct.get()!= null) {weakAct.get().textview.setText("");}
break;? ????????...????????}}}
(2) context,靜態(tài)View,單例模式
在一些需要傳遞context對象的方法中,盡量使用context.getApplicationContext();
靜態(tài)對象生命周期長,比如單例模式,單例模式變量的生命周期是跟應(yīng)用程序一樣長的,如果在初始化的時候調(diào)用并持有了某個Activity的引用,那么這個Activity就無法被回收。靜態(tài)的view也同理
(3) 變量聲明盡量縮小作用域
比如某個變量只在某個方法中調(diào)用了,這個變量就不需要定義成全局變量(這時候android studio會給警告的),能private的就別用public。
未完待續(xù).........