android 内存泄露

内存泄露情况:

1:使用单例导致内存泄露

public class Singleton {
    private static Singleton singleton=null;
    private Context context;
    public Singleton(Context context) {
        this.context=context;
    }
    public static Singleton getSingleton(Context context) {
        if (null == singleton) {
            singleton=new Singleton(context);
        }
        return singleton;
    }
}

原因:静态的单例使它的生命周期与应用的生命周期一样长,context一般传的是Activity或者Service等上下文,如果退出Activity,activity就没有用了,但是静态单例还会持有Activity的引用,导致无法回收,导致内存泄露。

2.WebView造成的内存泄露

原因:webview加载网页后会长期占用内存而不能释放

处理:在activity的destory()时销毁它,释放内存

@Override
protected void onDestroy() {
    super.onDestroy();
    rl_root.removeView(mWebView);
    mWebView.clearHistory();
    mWebView.removeAllViews();    
}

3.动画造成的内存泄露

原因:activity在销毁的时候没有调用cancel方法,动画引用控件,控件引用activity,所以activity无法正常释放

处理:在activity的destory()时销毁它,释放内存

@Override
protected void onDestroy() {
    super.onDestroy();
    mAnimator.cancel();
}

4.资源未关闭导致内存泄露

处理:使用IO,Cursor后,关闭。

OutputStream out = null;  
try {  
    out = new FileOutputStream("");  
    // 自己操作
} catch (Exception e) {  
    e.printStackTrace();  
} finally {  
    try {  
        if (out != null) {  
            out.close();  
        }  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
} 
    Cursor cursor = null;

try{

        cursor = mContext.getContentResolver().query(uri,null,null,null,null);

        if(cursor != null){

        cursor.moveToFirst();

        //自己处理

        }


        }catch(Exception e){

        e.printStatckTrace();

        }finally{

        if(cursor != null){

        cursor.close();

        }

        }

5. 注册广播,未关闭,操作内存泄露

处理:在activity的destory()时销毁它,释放内存

@Override
protected void onDestroy() {
    super.onDestroy();
if(mReceiver != null){
   this.unregisterRecevier(mReceiver);
 }
}

6.非静态内部类导致内存泄露,比如handler

原因1:activity关闭了,handle的MessageQuue消队列里还有下次没有消息处理或者正在处理,导致activity无法回收。

处理:使用静态内部类加弱引用

public class ClassModelActivity extends Activity {

    private Handler mHandler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activityclassmodel);
        mHandler=new WeekHandler(this);

}

private static class WeekHandler extends Handler{
   private WeakReference<ClassModelActivity > weekActivity;

    public WeekHandler(ClassModelActivity activity) {
        weekActivity=new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        ClassModelActivity activity=weekActivity.get();
        if(activity != null){
            switch (msg.what){

            }
        }
    }
}

上面可以避免actiity内存泄露,但是messageQueue消息队列中可能还有消息消息,所以也将它清理调掉

   @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
    }
}

7.匿名内部类对象导致activit不能被回收

原因:直接new线程或者new AsyncTask,匿名内部类对象默认隐式持有activity对象的引用

处理:像上面一样使用静态内部类加弱引用的方式。

8. Timer和TimerTask导致内存泄露

原因:activity关闭时,Timer还在等待执行TimerTask,它持有activity对象,导致activity不能被回收

处理:activity销毁时,调用Timer和TimerTask的cancel方法。

@Override
protected void onDestroy() {
    super.onDestroy();
    mTime.cancel();
    mTimerTask.cancel();
}

猜你喜欢

转载自blog.csdn.net/sunshine_0707/article/details/81410266