androidengineers.Book a session

Best Practices and Code Quality

Memory & GC basics (JVM/Native notes)

article15 minHard

Reachability determines what remains in memory

Garbage collection reclaims objects that are no longer reachable; it cannot infer that a reachable object is no longer useful to your application. A long-lived collection or callback can therefore create a memory leak without manual allocation mistakes.

class ListenerRegistry {
    private val listeners = mutableListOf<() -> Unit>()
    fun add(listener: () -> Unit) { listeners.add(listener) }
    fun remove(listener: () -> Unit) { listeners.remove(listener) }
    fun notifyAllListeners() { listeners.toList().forEach { it() } }
}

A listener may capture a screen and retain it until removed. This example is not thread-safe; mutation during callbacks is handled only by iterating a snapshot. Resource cleanup still needs explicit ownership because GC does not reliably release files or subscriptions at the moment you want.

Kotlin/JVM and Kotlin/Native have different runtime implementations. Do not carry obsolete assumptions about Native's historical memory model into current projects.

Exercise

Register and unregister the same callback instance. Use a profiler to examine a deliberately retained object, then remove the retaining reference.

Check: forcing GC is not a fix for an object still reachable through your registry.

Reference: Kotlin/Native memory management

YOUR LEARNING JOURNEY

0 of 110 available lessons completed

Progress saved in this browser. No account needed.
Memory & GC basics (JVM/Native notes) | Kotlin Core Programming | Android Engineers