简体   繁体   中英

Android GC collect an object if event it has strong reference to Application (why is this happening?)

As Android developer I've heard many times that View(Activity/Fragments) shouldn't contain any reference to objects with longer lifecycle (Application for example) otherwise GC can't collect it and there will be a memory leak.

But today I've tried to reproduce this issue and got unexpectedly result – Activity is still being collected by GC even it has a reference to the Application class.

I ran it on 3 devices (api:22,24,28) and got the same result.

Here is the code I used for test:

View:

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!")
    }
}

Application:

class ApplicationContext : Application() {

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

    companion object {
        lateinit var inst:ApplicationContext
    }

    override fun onCreate() {
        super.onCreate()

        inst = this
    }
}

How I reproduce it:

  1. Turn on "Don't Keep Activities" in Developer options on Android device to force Activity killing

  2. Compile the code above

  3. Close(Minimize) the application and open it again several times. MainActivity.onCreate been fired every time when I close/open Activity

  4. Close(Minimize) the application

-x-> after 10-30 seconds I got the log that all created activities were finalized (garbage collected)

---> created activities shouldn't be garbage collected because they contain reference to the Application class

Does anyone have any idea why this is happening? Does that mean we don't have to worry about Activity leaks at all? :)

PS I've also done the same issue without "Don't Keep Activities" option

Okey, I've realized it when I remembered basic GC terms :)

GC collect an object when the root object (Application) is unable to rich the collected object.

In my case although MainActivity has the reference to Application instance, the Application instance still can't rich any MainActivity method or property, so when Android releases the activity, it is collected by GC.

If I had passed Activity reference or callback to Application class then MainActivity will not be collected by GC.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM