类似如下伪代码事实上可能会造成内存泄漏:
1 | public class MyActivity extends AppCompatActivity { |
所有的内部对象都肯定持有外部对象的引用,比如我们可以在 doInBackground 中调用 onCreate 方法:
1 | public class MyActivity extends AppCompatActivity { |
MyAsyncTask 是 MyActivity 的内部类,持有 MyActivity 的引用,所以可以调用 MyActivity 的 onCreate 方法。
Java 回收策略为:没有被 GC Root 直接或间接持有引用的对象,会被回收。GC Root 有以下三种:
- 运行中的线程;
- 静态对象,所有的 static 修饰的都不会被回收;
- 来自 native code 中的引用。
AsyncTask 中的线程可能在运行过程中,此时 Activity 退出了,由于 AsyncTask 中的线程在运行中,持有 Activity,Activity 释放不掉,造成内存泄露。AsyncTask 会导致内存泄露是因为它里面有线程,AsyncTask 的内存泄露,其它类型的线程方案(Thread、Executor、HandlerThread)一样都有,使用 AsyncTask,只要任务的时间不长,例如10秒之内,那就完全没必要做防止内存泄露的处理,最多是虚拟机晚了10秒回收。但如果 AsyncTask 的时间过长,例如几个小时,那事实上不应该放在 Activity 中启动该任务,需要放入一个单独的后台线程中。
参考资料:
腾讯课堂 HenCoder