内存泄漏场景
-
单例造成的内存泄漏 在Android开发中,常见的单例问题造成内存泄漏的场景如下:当创建这个单例的时候,由于需要传入一个Context,所以这个Context的生命周期的长短至关重要:如果此时传入的是 Application 的 Context,因为 Application 的生命周期就是整个应用的生命周期,所以没有任何问题。如果此时传入的是 Activity 的 Context,当这个 Context 所对应的 Activity 退出时,由于该 Context 的引用被单例对象所持有,其生命周期等于整个应用程序的生命周期,所以当前 Activity 退出时它的内存并不会被回收,这就造成泄漏了。当然,Application 的 context 不是万能的,所以也不能随便乱用,例如Dialog必须使用 Activity 的 Context。
-
非静态内部类创建静态实例造成的内存泄漏 非静态内部类默认会持有外部类的引用,而该非静态内部类又创建了一个静态的实例,该实例的生命周期和应用的一样长,这就导致了该静态实例一直会持有该Activity的引用,导致Activity的内存资源不能正常回收。
-
匿名内部类造成的内存泄漏 匿名内部类默认也会持有外部类的引用。 如果在Activity/Fragment中使用了匿名类,并被异步线程持有,如果没有任何措施这样一定会导致泄漏。例子:Handler造成的内存泄漏。 修复方法:在 Activity 中避免使用非静态内部类或匿名内部类,比如将 Handler 声明为静态的,则其存活期跟 Activity 的生命周期就无关了。如果需要用到Activity,就通过弱引用的方式引入 Activity,避免直接将 Activity 作为 context 传进去。另外, Looper 线程的消息队列中还是可能会有待处理的消息,所以我们在 Activity 的 Destroy 时或者 Stop 时应该移除消息队列 MessageQueue 中的消息。