Our team noticed that non-static inner classes are preventing outer activities and objects from being garbage collected. What causes memory leaks in Java applications when utilizing inner classes, and how can we safely pass these instances around without retaining heavy objects?
3 answers
Non-static inner classes, including anonymous inner classes often used for event handlers or threads, maintain an implicit, hidden reference to their enclosing outer class instance. If the inner class instance is passed to a long-lived framework component or a background thread, the entire outer class remains anchored in memory alongside it. This means even if your application no longer uses the outer class object, the Garbage Collector cannot touch it because that hidden internal link is still active.
If we switch all of our nested classes to static ones, how can we still access the variables of the outer class when needed?
We ran into this constantly with asynchronous background tasks holding onto UI views before we forced a migration to static nested structures.
That is a classic mobile and desktop app issue, Victoria. Switching to static nested classes saves a massive amount of heap memory.
Gregory, to access outer variables from a static nested class, you should explicitly pass a WeakReference of the outer class into the nested class constructor. This allows you to call the outer methods without creating a strong memory retention link that blocks the GC.