如果事件具有对Application的强引用,则Android GC会收集对象(为什么会发生这种情况?)

时间:2019-04-08 15:43:42

标签: android garbage-collection

作为Android开发人员,我已经多次听到View(Activity / Fragments)不应包含对生命周期较长的对象的任何引用(例如Application),否则GC无法收集它,并且会发生内存泄漏。

但是今天,我试图重现此问题并得到意外的结果–即使它引用了Application类,活动仍由GC收集。

我在3个设备(api:22、24、28)上运行它,并得到了相同的结果。

这是我用于测试的代码:

查看:

class MainActivity : AppCompatActivity() {

    var gcBlocker = ApplicationContext.inst.list

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d("custom_masher", "CREATE!")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        gcBlocker.forEach {
            Log.d("app", it.toString())
        }
    }

    fun finalize(){
        Log.d("custom_masher", "FINALIZE!")
    }
}

应用程序:

class ApplicationContext : Application() {

    var list = listOf<Int>(1, 2, 3)

    companion object {
        lateinit var inst:ApplicationContext
    }

    override fun onCreate() {
        super.onCreate()

        inst = this
    }
}

我如何复制它:

  1. 在Android设备的“开发人员”选项中打开“不保留活动”以强制杀死活动

  2. 编译上面的代码

  3. 关闭(最小化)应用程序,然后再次打开它几次。每次我关闭/打开Activity时都会触发MainActivity.onCreate

  4. 关闭(最小化)应用程序

-x-> 10-30秒后,我得到所有创建的活动都已完成(收集垃圾)的日志

--->创建的活动不应被垃圾回收,因为它们包含对Application类的引用

有人知道为什么会这样吗?这是否意味着我们完全不必担心活动泄漏? :)

PS我也做了同样的问题,没有“不保留活动”选项

1 个答案:

答案 0 :(得分:0)

Okey,当我想起基本的GC术语时,我已经意识到了这一点:)

当根对象(应用程序)无法丰富收集的对象时,GC收集一个对象。

在我的案例中,尽管MainActivity引用了Application实例,但是Application实例仍然无法提供任何MainActivity方法或属性,因此,当Android发布活动时,该活动将由GC收集。

如果我已将Activity引用或回调传递给Application类,则GC将不会收集MainActivity。