Android内存泄漏的几种案例

1、单例和工具类造成的内存泄漏

单例是造成内存泄漏最常见的一种形式,单例对象的生命周期与Application一样长,当单例对象持有activity的引用的时候,activity销毁时候本该被内存回收,却无法回收,这就造成了内存泄漏。


public class AppManager {
    private static AppManager instance;
    private Context context;
    private AppManager(Context context) {
        this.context = context;
    }
    public static AppManager getInstance(Context context) {
        if (instance != null) {
            instance = new AppManager(context);
        }
        return instance;
    }

解决办法: 将持有的context对象改为全局的ApplicationContext引用

public class AppManager {
    private static AppManager instance;
    private Context context;
    private AppManager(Context context) {
        this.context = context.getApplicationContext();
    }
    public static AppManager getInstance(Context context) {
        if (instance != null) {
            instance = new AppManager(context);
        }
        return instance;
    }
}

2、内部类造成的内存泄漏

非静态内部类会隐式持有外部类的引用。那么很常见的一类就是Handler和AsyncTask造成的内存泄漏了

比如,Handler的常见写法:


public class MainActivity extends AppCompatActivity {
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            //...
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        loadData();
    }
    private void loadData(){
        //...request
        Message message = Message.obtain();
        mHandler.sendMessage(message);
    }
}

这时候如果Activity该销毁了而handler里面还有任务未执行完毕,就会造成内存泄漏。

解决办法:将其改为Handler持有activity的弱引用

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "MainActivity";
    private Handler mHandler = new MainHandler(this);
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.tv);
        mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mHandler.sendMessage(Message.obtain());
            }
        });
    }

    class MainHandler extends Handler {
        private WeakReference<MainActivity> wrf;

        public MainHandler(MainActivity mainActivity) {
            wrf = new WeakReference<MainActivity>(mainActivity);
        }

        @Override
        public void handleMessage(Message msg) {
            MainActivity mainActivity = wrf.get();
            mainActivity.mTextView.setText("jack is handsome");
        }
    }


}

同理AsynTask也会造成一样的内存泄漏,解决办法跟Handler一样。

3、数据库,文件流等使用完未及时关闭。

对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的代码,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。

4、监听器没有注销造成的内存泄漏

在Android程序里面存在很多需要register与unregister的监听器,我们需要确保及时unregister监听器。

感谢博主:https://blog.csdn.net/qq_35373333/article/details/74909811

https://blog.csdn.net/u012482178/article/details/78988176

猜你喜欢

转载自blog.csdn.net/fisheryujie/article/details/81698325
今日推荐