android防内存泄漏与内存优化的方法整理

内存泄漏

一、单利泄漏

存在内存泄露问题的一些代码片段像下面这样:

 public class Util {  

           private Context mContext;  

           private static Util sInstance;  

           private Util(Context context) {  

               this.mContext = context;  

         }  

        public static Util getInstance(Context context) {  

            if (sInstance == null) {  

              sInstance = new Util(context);  

            }  

           return sInstance;  

     }  

}

假设Activity  A 里使用Util类:

Util.getInstance(this); 

代码大意就是这样,这样写的问题就是,在Activity A 里使用Util类,传入的context 是 actvitiy-context。试想一下,当Activity A 生命周期结束,但Util类里面却还存在A的引用 (mContext),这样Activity A占用的内存就一直不能回收,而A的对象也不会再被使用。本人写代码测试过,在A中调用了finish(),A的destroy()方法也被执行了,但其占用的内存,比如说,ImageView占用的内存,还是不能释放的。

那么如何解决这个问题呢?在A中,可以用Util.getInstance(getApplicationContext());或Util.getInstance(getApplication()); 代替。 

因为Application的生命周期是贯穿整个程序的,所以Util类持有它的引用,也不会造成内存泄露问题。

 

 

2、资源使用完未关闭

一、动态注册广播,一定要在onDestroy  调用unregisterReceiver 取消注册,不然当activity结束后,广播不被回收,导致内存泄漏。

二、io Cursor 流要记得close,一定要在finally去close 防止抛异常没执行close 。

三、bitmap 使用时要记录recycle,不注意,很容易出现ANR。

 

3、Handler造成内存泄露,

          方法一:通过程序逻辑来进行保护。
          1.在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,Activity自然会在合适的时候被回收。 
          2.如果你的Handler是被delay的Message持有了引用,那么使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行了。

            方法二:将Handler声明为静态类。

4、AsyncTask内存泄露

         在销毁当前Activity的时候手动去调用AsyncTask的cancle方法,(activity 结束后,AsyncTask会在doInBackground()方法执行完毕之后再结束)

内存优化

1、尽量使用StringBuilder,不要用"+"去拼接字符串,浪费不必要的内存。

2、图片能压缩,尽量压缩。

3、尽量使用池:线程池,缓存池,okhttp里面的connectionPool(Socket复用池),okio SegmentPool(buffer复用池)------(可以重复        使用对象,减少内存开销,内存拉动,cpu开销)

4、常用的数据结构优化:  能用SparseArray就不用HashMap.

5、xml层级和view :xml层级最好控制在5层以内,多用ViewStub ,include,merge。

 

 

 

猜你喜欢

转载自blog.csdn.net/ieiqny1/article/details/81231638