zoukankan      html  css  js  c++  java
  • Android常见内存泄露优化总结

    进行android总结,总结了一些自己写的以及常见的android内存泄露的优化,如有错误以及不全的地方请大家帮忙指正,谢谢!!!

    1、Activity Fragment用了 static
    例如:

    public class MainActivity extends ActionBarActivity{
    public static MainActivity mainActivity;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainActivity=this;
      }
    }
    

    如此写了之后在其他的地方调用MainActivity.mainActivity...

    只要有对象持有了这个mainActivity,MainActivity就不会被回收,里面的所有的数据包括View不会被回收,容易出现内存泄露
    不同界面之间的数据传输用intnent等进行传递,该缓存的数据进行缓存,数据库,文件,sp都可以。

    2、Activity Fragment用了 别的对象持有了该对象
    例如MyManager.getInstance().addListener(this);
    能用getApplicationContext()就用getApplicationContext();只能用这个对象的在onDestroy()的时候要清除持有的的该对象

    3、Handler
    1)、如果handler中new了很多重复的message,会存在内存泄露,可以调用handler.removeMessages(what);
    在onDestroy()的时候的时候最好调用handler.removeMessages(what);
    2)、

    public class MainActivity extends Activity {
      //...
      Handler handler;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...
        handler = new Handler() {
          @Override
          public void handleMessage(Message msg) {
        }
      }
    }


    如果调用了handler.postDeslayed,如果delay的时间过长,此时Activity不会被回收,可以onDestroy()的时候handler.removeMessages(what);
    还可以用下面的写法

    private static class MyHandler extends Handler { 
    private final WeakReference<MainActivity> mActivity; 
    // ...
    public MyHandler(MainActivity activity) {
      mActivity = new WeakReference<MainActivity>(activity);
      //... 
    }
    @Override
    public void handleMessage(Message msg) { 
    }
    //...
    }


    WeakReference,也就是所谓的弱引用。垃圾回收器在回收的时候,是会忽视掉弱引用的,所以包含它的 Activity 会被正常清理掉

    4、线程造成的内存泄露
    对于线程造成的内存泄漏,也是平时比较常见的,下面的写法:

    new AsyncTask<Void, Void, Void>() {
      @Override
      protected Void doInBackground(Void... params) {
        SystemClock.sleep(10000);
        return null;
      }
    }.execute();

    上面的异步任务是一个匿名内部类,因此它们对当前Activity都有一个隐式引用。如果Activity在销毁之前,任务还未完成,
    那么将导致Activity的内存资源无法回收,造成内存泄漏。正确的做法还是使用静态内部类的方式,如下

    static class MyAsyncTask extends AsyncTask<Void, Void, Void> {
        private WeakReference<Context> weakReference;
        public MyAsyncTask(Context context) {
            weakReference = new WeakReference<>(context);
        }
        @Override
        protected Void doInBackground(Void... params) {
            SystemClock.sleep(10000);
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            MainActivity activity = (MainActivity) weakReference.get();
            if (activity != null) {
            //...
            }
        }
    }                

    5、资源未关闭造成的内存泄漏
    对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。
    BraodcastReceiver动态注册的需要unRegister(..)
    Cursor需要close()
    Stream也需要close()
    Bitmap需要recyle()

    6、Adapter每次new View,可以用下面的写法,ListView和GridView可以重复的利用View

    public View getView(int position, View convertView, ViewGroup arg2) {
    
        ViewHolder vh = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_list, null);
            vh = new ViewHolder();
            vh.tv = (TextView) convertView.findViewById(R.id.tv);
            convertView.setTag(vh);
        } else {
            vh = (ViewHolder) convertView.getTag();
        }
        vh.tv.setText("");
        return convertView;
    }
    
    public static class ViewHolder {
        public TextView tv;
    }

    7、 移除掉所有的静态引用。
    考虑用 EventBus 来解耦 Listener,在不需要的时候,解除 Listener 的绑定。
    尽量用静态内部类。
    做 Code Review。
    用类似 MAT,Eclipse Analyzer,LeakCanary 这样的工具分析内存。
    在 Callback 输出 Log。

  • 相关阅读:
    mui h5 动态实现数据的移除和数据操作完后的重新获取
    mui H5 js动态添加不同类型的数据
    hbuider 中点击就显示出一个单选的列表 ,然后后台跨域向里面动态添加数据,注意里面的格式是json object
    H-UI的前端处理验证,判断是否已经存在,比较健全的模板,可以自己添加一些校验
    spring mvc 和mybatis整合 的异常处理
    列表显示数据 但是数据的字体颜色要js添加
    hadoop环境都配置好后,当运行sbin下的start-hdfs.sh时报WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform...错误
    VisualVM初次使用BTrace功能方法步骤
    二叉树--递归实现
    二叉树--非递归实现
  • 原文地址:https://www.cnblogs.com/xunzhi/p/5041595.html
Copyright © 2011-2022 走看看