1、单例造成的内存泄露
当调用getInstance时,如果传入的context是activity的context。
只要这个单例没有被释放,那么这个activity也不会被释放一直到进程退出时才会释放
解决方案:
能使用Application的Context就不要使用Activity的content,Application的生命周期伴随着整个进程的周期
2、非静态内部类创建静态实例造成的内存泄露
解决方案:
将非静态内部类修改为静态内部类。(静态内部类不会隐式持有外部类)
3、Handler造成的内存泄露
mHandler是Handler的非静态匿名内部类的实例,所以它持有外部类Activity的引用,我们知道消息队列是在一个Lopper线程中不断轮询处理消息,那么当这个Activity退出时消息队列中还有未处理的消息或者正在处理消息,而消息队列中的Message持有mHandler实例的引用,mHandler又持有Activity的引用,所以导致该Activity的内存资源无法及时回收,引发内存泄露。
解决方案:
创建一个静态Handler内部类,然后对Handler持有的对象使用弱引用,这样在回收时也可以回收Handler持有的对象,这样虽然避免了Activity泄露,不过Looper线程的消息队列中还是可能会有待处理的消息,所以我们在Activity的Destory时或者Stop时应该移除消息队列中的消息
4、线程造成的内存泄露
异步任务和Runnable都是一个匿名内部类,因此它们对当前Activity都有一个隐式引用。如果Activity在销毁之前,任务还未完成,那么将导致Activity的内存资源无法回收,造成内存泄露
解决方法
使用静态内部类,避免Activity的内存资源泄露,当然在Activity销毁时候也应该取消相应的任务AsyncTask::cancel(),避免任务在后台执行浪费资源
5、资源未关闭造成的内存泄露
对于使用了BroadcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄露
解决方案
在Activity销毁时及时关闭或者注销
6、使用了静态的Activity和View
解决方案
应该及时将静态的应用置为null,而且一般不建议将View及Activity设置为静态
7、注册科系统的服务,但onDestory未注销
解决方案
8、不需要用的监听未移除会发生内存泄露
解决方案
tv.setOnClickListener();监听执行完回收对象,不用考虑内存泄露
tv.getViewTreeObserver().addOnWindowFocusChangeListener,add监听,放到集合里面,需要考虑内存泄露