Open Sogrey opened 5 years ago
什么时候会发生内存泄露?内存泄露的根本原因:长生命周期的对象持有短生命周期的对象。短周期对象就无法及时释放。
1. 静态集合类引起内存泄露
主要是hashmap,Vector等,如果是静态集合 这些集合没有及时setnull的话,就会一直持有这些对象。
2. remove 方法无法删除set集 Objects.hash(firstName, lastName);
经过测试,hashcode修改后,就没有办法remove了。
3. observer 我们在使用监听器的时候,往往是addxxxlistener,但是当我们不需要的时候,忘记removexxxlistener,就容易内存leak。
广播没有unregisterrecevier
4. 各种数据链接没有关闭,数据库contentprovider,io,sokect等。cursor
5. 内部类:
java中的内部类(匿名内部类),会持有宿主类的强引用this。
所以如果是new Thread这种,后台线程的操作,当线程没有执行结束时,activity不会被回收。
Context的引用,当TextView 等等都会持有上下文的引用。如果有static drawable,就会导致该内存无法释放。
6. 单例
单例 是一个全局的静态对象,当持有某个复制的类A是,A无法被释放,内存leak。
一、Handler 引起的内存泄漏。 解决:将Handler声明为静态内部类,就不会持有外部类SecondActivity的引用,其生命周期就和外部类无关,如果Handler里面需要context的话,可以通过弱引用方式引用外部类
二、单例模式引起的内存泄漏。 解决:Context是ApplicationContext,由于ApplicationContext的生命周期是和app一致的,不会导致内存泄漏
三、非静态内部类创建静态实例引起的内存泄漏。 解决:把内部类修改为静态的就可以避免内存泄漏了
四、非静态匿名内部类引起的内存泄漏。 解决:将匿名内部类设置为静态的。
五、注册/反注册未成对使用引起的内存泄漏。 注册广播接受器、EventBus等,记得解绑。
六、资源对象没有关闭引起的内存泄漏。 在这些资源不使用的时候,记得调用相应的类似close()、destroy()、recycler()、release()等方法释放。
七、集合对象没有及时清理引起的内存泄漏。 通常会把一些对象装入到集合中,当不使用的时候一定要记得及时清理集合,让相关对象不再被引用。