如果引用超出范围,为什么 AsyncTask 不会被垃圾回收?

Why is AsyncTask not garbage collected if reference is out of scope?

我正在使用 AsyncTask 在 ListView 中加载一些图像。它看起来像这样:

private void loadImageInBackground(ViewHolder holder, Location location) {
    ImageViewLoader coverImageLoader = new ImageViewLoader(holder.locationImage, coversImgCache);
    coverImageLoader.execute(location.getImageUrl());
}

其中 ImageViewLoader 只是一个扩展的 AsyncTask。

据我了解,垃圾收集器会收集不再引用的所有内容。

随着堆栈指针离开上面的函数,class 会丢失对创建的 ImageViewLoader 对象的所有引用。这应该被垃圾收集,不是吗?

但是,AsyncTask 仍在工作并最终回调 onPostExecute

我的一个猜测是它创建了一个线程并且该线程具有对该对象的引用。一旦线程死亡,AsyncTask 也会被垃圾回收。

我的猜测是否接近实际答案?

One of my guesses is that it creates a thread and that thread has a reference to the object. As soon as the thread dies, the AsyncTask is also garbage collected.

没错。一个线程 is considered a GC root。此线程引用了 AsyncTask,导致无法收集它。

尽管如此,如果它应该被收集,即使在 onPostExecute 被调用之前,您也不能依赖垃圾收集器。

AsyncTask 只是 java 工作线程的包装器。因此,当您的主进程处于活动状态时,您的工作线程将 运行 而不是 GC。完成后,AsyncTask 在主线程上执行 onPostExecute(),这意味着工作线程已死,AsyncTask 可以作为普通对象收集。