什么 is/are GC 根对象引用 Java 外部和内部 类?

What is/are GC root objects referencing Java outer and inner classes?

所以我对 android 中的内存泄漏进行了大量研究,并阅读了许多 Whosebug post。我仍然不明白的是,根据 Medium 和 Whosebug posts(下面提到的链接),如果我将 activity 的上下文传递给 Recyclerview 的适配器并将其存储为全局变量在适配器中,我的 activity 和适配器仍然有资格进行垃圾回收。这是因为 没有 GC roots 引用适配器或我的 activity (一旦它被销毁),所以两者都将被垃圾收集 (示例 1)。但是,为什么不对内部 classes 应用相同的情况?我知道他们持有对他们持有的 class 的隐式引用,但是如果 activity(在这种情况下持有 class)被销毁,即使内部 class 仍在执行一些异步任务,不应该 没有 GC 根 指向它们中的任何一个吗? (holding or the inner class) 所以他们两个都应该收集垃圾? (示例 2)

示例 1:(在 activity 被销毁后符合 GC 条件):

public class MyAdaptor extends RecyclerView.Adaptor<>{

public Context context;

public MyAdaptor(Context context){
this.context=context;
}

}



public MyActivity extends AppCompatActivity {
private MyAdaptor myAdaptor;    

@Override
protected void onCreate(Bundle savedInstanceState) {
//some code
myAdaptor=new MyAdaptor(this);
}

}

示例 2:(activity 被销毁后不符合 GC 条件):

public MyHoldingActivity extends AppCompatActivity {
private MyInnerClass myInnerClass;    

@Override
protected void onCreate(Bundle savedInstanceState) {
myInnerClass=new MyInnerClass();
}

class MyInnerClass{
//executing some long Async Task
}

}

我提到的两个 post 的链接如下: https://medium.com/@oznusem/circular-dependency-in-android-should-i-worry-about-it-814660ac79ec

抱歉,如果我没有说清楚我的问题,这是我在 Whosebug 上的第一个 post。

假设 AsyncTask 引用了您的内部 class,那么:

如果一个Activity的内部class是运行一个AsyncTask,即使Activity完成了,GC也无法回收 Activity 因为内部 class 引用了 ActivityAsyncTask 引用了内部 class 和 Android的内部线程管理器引用了 AsyncTask。但是,一旦 AsyncTask 完成,GC 就可以回收 Activity,因为内部线程管理器将不再引用 AsyncTask.

这并不是真正的内存泄漏,因为这只是暂时的情况。 Activity 最终会被回收。真正的 "memory leaks" 发生在对象 永远不会 被 GC 回收时。最终,此类内存泄漏会消耗所有可用内存并导致长 运行 应用程序崩溃并出现 OutOfMemoryException.

您可以通过取消 ActivityonDestroy() 中的 AsyncTask 来防止这种情况发生。

希望这能回答您的问题。